UI-Router Sample App
Explore the Sample App for:
UI-Router 1.0 Sample Application
The sample app is intended to demonstrate a non-trivial ui-router application. It models the following
- Multiple application feature modules
- Authentication (simulated)
- Authenticated and unauthenticated states
- State lifecycle management
- Application data retrieval
- REST data retrieval (simulated)
Visualizer
We’re using the State and Transition Visualizer to visually represent the current state tree, as well as the transitions between states. Explore how transitions work by hovering over them, and clicking to expand details (params and resolves).
Note how states are entered when they were previously not active, exited and re-_entered_ when parameters change,
and how parent states whose parameters did not change are retained.
Each of these (exited, entered, retained) correspond to a Transition Hook.
Structure
The application utilizes ES6 modules.
There are many ways to structure a ui-router app. We aren’t super opinionated on application structure. Use what works for you. We organized ours in the following way:
- Sub-module (feature) organization
- Each feature gets its own directory.
- Features contain state definitions, components, and other code such as services.
- Leverage ES6 modules
- Each thing (component, state, service) is defined in its own file (ES6 module) and is exported.
- Each feature module has an index file which imports the code, and composes them together (as the feature module), then re-exports them.
- At the top level, the bootstrap imports all the features and composes the application, registering services and states with UI-Router, etc.
UI-Router Patterns
- Default substate for a top-level state
- Example: the
mymessages
state specifiesredirectTo: 'mymessages.folder'
. When the user tries to activatemymessages
(e.g., using a ui-sref link or a bookmark), the transition is redirected tomymessages.folder
.
- Example: the
- Defining a default parameter for a state
- Example: the
folderId
parameter of thefolder
state defaults to a value of ‘inbox’.
- Example: the
- Application data lifecycle (resolve)
- Data loading is managed by the state declaration, via the
resolve:
block - Data is fetched before the state is entered
- Data is fetched according to state parameters
- The state is entered when the data is ready
- The resolved data is provided to the components
- The resolve data is accessible until the state is exited
- Data loading is managed by the state declaration, via the
- Data dirty checking and confirmation hooks
- Example: The
contacts.edit
state allows a user to edit contact details using a form. If a user has modified data in the form, then tries to activate a different state, the edit contact component will prompt for confirmation before allowing the transition to exitcontacts.edit
.
- Example: The
- Custom application behaviors using declarative Transition Hooks.
- The
authRequired
hook checks for state metadata, which declares that a state requires authentication. When a transition starts, the inspects the destination state’sdata.authRequired: true
property. If it’s truthy, then it checks that the user is authenticated, or redirects to the login state.
- The