¿Cómo evito que vuelva a cargarse en la vista especificada cuando cambia el estado? AngularJS UI-Router

Estoy usando el excelente módulo ui-router en mi aplicación. Como parte de esto, estoy usando vistas con nombre para administrar la ‘subnavegación dinámica’ que tengo en la aplicación.

Considera lo siguiente:

 $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' } } }); 

Cuando los usuarios visitan por primera vez la aplicación, se les presenta una lista de personas. Cuando hacen clic en una persona, se llevan a la página de detalles. Bastante básico. Aquí está el marcado si ayuda …

 

Sin embargo, el PersonNavController llama a un servicio REST para obtener una lista de personas, de modo que cuando se ve a una persona, el usuario puede navegar por elementos hermanos. El uso del método anterior hace que la plantilla y el controlador vuelvan a procesarse, lo que provoca un retraso después de cada clic, a pesar de que el contenido nunca cambia.

¿Hay alguna forma de mantener cargada la vista 'nav@' y solo actualizar la vista 'main@' ?

La forma en que estoy usando ui-router en estos escenarios es: mover las vistas al mínimo común denominador .

Otras palabras: en caso de que ui-view="nav" se comparta entre todos los detalles y es el mismo para todos ellos (porque debe cargarse solo una vez) – debe ser parte del estado de la list (principal del detail estado)

la definición del estado padre se ajustaría así:

 .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" 'nav@person.list': { templateUrl: "person.nav.html", controller: 'PersonNavController' } } 

Entonces, ¿dónde está el truco? En el poder del ui-router angular. Podemos, durante cada definición de estado , dirigirnos a la vista actual . Ahora, la vista de nav es parte de la definición de estado de la list , es decir, no se volverá a cargar durante la conmutación de detalles (también consulte aquí para obtener más información).

Solo tenemos que usar las convenciones de nomenclatura definidas, ver:

  • Ver nombres – Nombres relativos vs. absolutos

Pocas líneas citadas de la documentación mencionada:

 views: { //////////////////////////////////// // Relative Targeting // // Targets parent state ui-view's // //////////////////////////////////// // Relatively targets the 'detail' view in this state's parent state, 'contacts'. // 
within contacts.html "detail" : { }, // Relatively targets the unnamed view in this state's parent state, 'contacts'. //
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'. //
within contacts.detail.html "info@contacts.detail" : { } // Absolutely targets the 'detail' view in the 'contacts' state. //
within contacts.html "detail@contacts" : { }