I'm using the excellent ui-router
module in my application. As part of this, I'm using named views to manage the 'dynamic sub-navigation' I have in the app.
Consider the following:
$urlRouterProvider.otherwise('/person/list'); $stateProvider .state('person', { url: '/person', abstract: true, }) .state('person.list', { url: '/list', views: { "main@": { templateUrl: "person.list.html", controller: 'PersonListController' } } }) .state('person.details', { url: '/{id}', views: { 'main@': { templateUrl: "person.details.html", controller: 'PersonController' }, 'nav@': { templateUrl: "person.nav.html", controller: 'PersonNavController' } } });
When users first visit the app, they are presented with a list of people. When they click on a person, they are taken to the details page. Pretty basic stuff. Here's the markup if it helps...
<div> <aside ui-view="nav"></aside> <div ui-view="main"></div> </div>
However, the PersonNavController
calls a REST service to get a list of people, so when viewing a person, the user is able to navigate sibling elements. Using the method above causes the template and controller to re-render, thus causing a delay after every click, despite the content never changing.
Is there a way to keep the 'nav@'
view loaded, and only refresh the 'main@'
view?
The way I am using ui-router
in this scenarios is: move the views to the least common denominator.
Other words: In case that ui-view="nav"
is shared among all the details and is the same for all of them (because it should be loaded only once) - it should be part of the list
state (parent of the detail
state)
the parent state defintion would be adjusted like this:
.state('person.list', { url: '/list', views: { "main@": { templateUrl: "person.list.html", controller: 'PersonListController' } // here we target the person.list.html // and its ui-view="nav" '[email protected]': { templateUrl: "person.nav.html", controller: 'PersonNavController' } }
So where is the trick? In the power of the angular ui-router
. We can, during each state defintion, target the current view. Now, the nav
view is part of the list
state definition - i.e. it will not be reloaded during the detail switching (also check here for more explanation)
We just have to use the defined naming conventions, see:
Few cited lines from the mentioned documentation:
views: { //////////////////////////////////// // Relative Targeting // // Targets parent state ui-view's // //////////////////////////////////// // Relatively targets the 'detail' view in this state's parent state, 'contacts'. // <div ui-view='detail'/> within contacts.html "detail" : { }, // Relatively targets the unnamed view in this state's parent state, 'contacts'. // <div ui-view/> within contacts.html "" : { }, /////////////////////////////////////////////////////// // Absolute Targeting using '@' // // Targets any view within this state or an ancestor // /////////////////////////////////////////////////////// // Absolutely targets the 'info' view in this state, 'contacts.detail'. // <div ui-view='info'/> within contacts.detail.html "[email protected]" : { } // Absolutely targets the 'detail' view in the 'contacts' state. // <div ui-view='detail'/> within contacts.html "detail@contacts" : { }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With