Ya se ha preguntado antes, y por las respuestas no se ve bien. Me gustaría preguntar con este código de muestra en consideración ...
Mi aplicación carga el elemento actual en el servicio que lo proporciona. Hay varios controladores que manipulan los datos del elemento sin que el elemento se vuelva a cargar.
Mis controladores volverán a cargar el elemento si aún no está configurado; de lo contrario, utilizará el elemento actualmente cargado del servicio, entre los controladores.
Problema : me gustaría usar diferentes rutas para cada controlador sin volver a cargar Item.html.
1) ¿Es eso posible?
2) Si eso no es posible, ¿hay un mejor enfoque para tener una ruta por controlador en comparación con lo que se me ocurrió aquí?
app.js
var app = angular.module('myModule', []).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/items', {templateUrl: 'partials/items.html', controller: ItemsCtrl}).
when('/items/:itemId/foo', {templateUrl: 'partials/item.html', controller: ItemFooCtrl}).
when('/items/:itemId/bar', {templateUrl: 'partials/item.html', controller: ItemBarCtrl}).
otherwise({redirectTo: '/items'});
}]);
Item.html
<!-- Menu -->
<a id="fooTab" my-active-directive="view.name" href="#/item/{{item.id}}/foo">Foo</a>
<a id="barTab" my-active-directive="view.name" href="#/item/{{item.id}}/bar">Bar</a>
<!-- Content -->
<div class="content" ng-include="" src="view.template"></div>
controller.js
// Helper function to load $scope.item if refresh or directly linked
function itemCtrlInit($scope, $routeParams, MyService) {
$scope.item = MyService.currentItem;
if (!$scope.item) {
MyService.currentItem = MyService.get({itemId: $routeParams.itemId});
$scope.item = MyService.currentItem;
}
}
function itemFooCtrl($scope, $routeParams, MyService) {
$scope.view = {name: 'foo', template: 'partials/itemFoo.html'};
itemCtrlInit($scope, $routeParams, MyService);
}
function itemBarCtrl($scope, $routeParams, MyService) {
$scope.view = {name: 'bar', template: 'partials/itemBar.html'};
itemCtrlInit($scope, $routeParams, MyService);
}
Resolución.
Estado : el uso de la consulta de búsqueda como se recomienda en la respuesta aceptada me permitió proporcionar diferentes URL sin volver a cargar el controlador principal.
app.js
var app = angular.module('myModule', []).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/items', {templateUrl: 'partials/items.html', controller: ItemsCtrl}).
when('/item/:itemId/', {templateUrl: 'partials/item.html', controller: ItemCtrl, reloadOnSearch: false}).
otherwise({redirectTo: '/items'});
}]);
Item.html
<!-- Menu -->
<dd id="fooTab" item-tab="view.name" ng-click="view = views.foo;"><a href="#/item/{{item.id}}/?view=foo">Foo</a></dd>
<dd id="barTab" item-tab="view.name" ng-click="view = views.bar;"><a href="#/item/{{item.id}}/?view=foo">Bar</a></dd>
<!-- Content -->
<div class="content" ng-include="" src="view.template"></div>
controller.js
function ItemCtrl($scope, $routeParams, Appts) {
$scope.views = {
foo: {name: 'foo', template: 'partials/itemFoo.html'},
bar: {name: 'bar', template: 'partials/itemBar.html'},
}
$scope.view = $scope.views[$routeParams.view];
}
directives.js
app.directive('itemTab', function(){
return function(scope, elem, attrs) {
scope.$watch(attrs.itemTab, function(val) {
if (val+'Tab' == attrs.id) {
elem.addClass('active');
} else {
elem.removeClass('active');
}
});
}
});
El contenido dentro de mis parciales está envuelto con ng-controller=...
Respuestas:
Si no tiene que usar URL como
#/item/{{item.id}}/foo
y#/item/{{item.id}}/bar
pero,#/item/{{item.id}}/?foo
y en su#/item/{{item.id}}/?bar
lugar, puede configurar su ruta para/item/{{item.id}}/
que sereloadOnSearch
establezca enfalse
( https://docs.angularjs.org/api/ngRoute/provider/$routeProvider ). Eso le dice a AngularJS que no vuelva a cargar la vista si cambia la parte de búsqueda de la URL.fuente
ng-controller="view.controller"
a lang-include
directiva.<div ng-controller="itemFooCtrl">... your template content...</div>
. EDITAR: Me alegra verte resuelto, sería genial si actualizaras tu pregunta con cómo lo resolviste, tal vez con un jsFiddle.Si necesita cambiar la ruta, agregue esto después de su .config en su archivo de aplicación. Entonces puedes hacer
$location.path('/sampleurl', false);
para evitar la recargaEl crédito va a https://www.consolelog.io/angularjs-change-path-without-reloading para obtener la solución más elegante que he encontrado.
fuente
$timeout(un, 200);
antes de la declaración de devolución ya que a veces$locationChangeSuccess
no se disparó en absoluto despuésapply
(y la ruta no se cambió cuando realmente se necesitaba). Mi solución aclara las cosas después de invocar la ruta (..., falso)¿por qué no simplemente poner el controlador ng un nivel más alto,
Y no configure el controlador en la ruta,
esto funciona para mi.
fuente
Para aquellos que necesitan un cambio de ruta () sin recargar los controladores: aquí está el complemento: https://github.com/anglibs/angular-location-update
Uso:
Basado en https://stackoverflow.com/a/24102139/1751321
PD Esta solución https://stackoverflow.com/a/24102139/1751321 contiene un error después de la ruta (falsa) llamada: interrumpirá la navegación del navegador hacia atrás / adelante hasta que la ruta (verdadera) llame
fuente
Aunque esta publicación es antigua y se ha aceptado una respuesta, el uso de reloadOnSeach = false no resuelve el problema para aquellos de nosotros que necesitamos cambiar la ruta real y no solo los parámetros. Aquí hay una solución simple a considerar:
Use ng-include en lugar de ng-view y asigne su controlador en la plantilla.
El único inconveniente es que no puede usar el atributo resolver, pero eso es bastante fácil de manejar. También debe administrar el estado del controlador, como la lógica basada en $ routeParams a medida que la ruta cambia dentro del controlador a medida que cambia la url correspondiente.
Aquí hay un ejemplo: http://plnkr.co/edit/WtAOm59CFcjafMmxBVOP?p=preview
fuente
Yo uso esta solucion
Este enfoque conserva la funcionalidad del botón de retroceso, y siempre tiene los routeParams actuales en la plantilla, a diferencia de otros enfoques que he visto.
fuente
Las respuestas anteriores, incluida la de GitHub, tuvieron algunos problemas para mi escenario y también el botón de retroceso o el cambio directo de URL desde el navegador estaba recargando el controlador, lo que no me gustó. Finalmente fui con el siguiente enfoque:
1. Defina una propiedad en las definiciones de ruta, llamada 'noReload' para aquellas rutas en las que no desea que el controlador se vuelva a cargar en el cambio de ruta.
2. En la función de ejecución de su módulo, coloque la lógica que verifica esas rutas. Evitará la recarga solo si
noReload
es asítrue
y el controlador de ruta anterior es el mismo.3. Finalmente, en el controlador, escuche el evento $ routeUpdate para que pueda hacer lo que sea necesario cuando cambien los parámetros de la ruta.
Tenga en cuenta que con este enfoque, no cambia las cosas en el controlador y luego actualiza la ruta en consecuencia. Es al revés. Primero cambia la ruta, luego escucha el evento $ routeUpdate para cambiar las cosas en el controlador cuando cambian los parámetros de la ruta.
Esto mantiene las cosas simples y consistentes, ya que puede usar la misma lógica tanto cuando simplemente cambia la ruta (pero sin costosas solicitudes de $ http si lo desea) como cuando recarga completamente el navegador.
fuente
Hay una manera simple de cambiar la ruta sin recargar
Use este código para cambiar la URL, la página no será redirigida
El segundo parámetro "falso" es muy importante.
fuente
Aquí está mi solución más completa que resuelve algunas cosas que @Vigrond y @rahilwazir se perdieron:
$routeUpdate
.$locationChangeSuccess
nunca se activa, lo que impide la próxima actualización de la ruta.Si en el mismo ciclo de resumen hubo otra solicitud de actualización, esta vez deseando volver a cargar, el controlador de eventos cancelará esa recarga.
fuente
path
al final debería serparam
, también esto no funciona con hashes, y la url en mi barra de direcciones no se actualizaAgregue la siguiente etiqueta dentro de la cabeza
Esto evitará la recarga.
fuente
Desde aproximadamente la versión 1.2, puede usar $ location.replace () :
fuente