Paginación de AngularJS con $ location.path pero sin carga de ngView

Mi aplicación de una sola página carga una página de inicio y quiero mostrar una serie de ideas. Cada una de las ideas se muestra en un contenedor flash animado, con animaciones que se muestran para alternar entre las ideas.

Las ideas se cargan usando $ http:

$scope.flash = new FlashInterface scope:$scope,location:$location $http.get("/competition.json") .success (data) -> $scope.flash._init data 

Sin embargo, para aprovechar el historial de navegación y UX, deseo actualizar la barra de direcciones para mostrar la url correcta para cada idea usando $ location:

 $location.path "/i/#{idea.code}" $scope.$apply() 

Estoy llamando $ aplicar aquí porque este evento proviene de fuera del contexto AngularJS, es decir, Flash. Me gustaría que el controlador / vista actual permanezca y que la vista no se vuelva a cargar. Esto es muy malo porque al volver a cargar la vista, el objeto flash completo se descarta y el ciclo del precargador comienza de nuevo.

He intentado escuchar $ routeChangeStart para hacer un preventDefault:

 $scope.$on "$routeChangeStart", (ev,next,current) -> ev.preventDefault() $scope.$on "$routeChangeSuccess", (ev,current) -> ev.preventDefault() 

pero fue en vano. Todo el asunto sería genial si pudiera encontrar una manera de anular la recarga de la vista cuando cambie $ location.path.

Todavía estoy sintiendo las cosas a mi manera en AngularJS, ¡así que estaría contento de cualquier sugerencia sobre cómo estructurar la aplicación para lograr mi objective!

En lugar de actualizar la ruta, simplemente actualice query param con un número de página.

establece tu ruta para ignorar los cambios de parámetros de consulta:

 .... $routeProvider.when('/foo', {..., reloadOnSearch: false}) .... 

y en su $location actualización de la aplicación con:

 ... $location.search('page', pageNumber); ... 

De esta publicación en el blog :

de forma predeterminada, todos los cambios de ubicación pasan por el proceso de enrutamiento, que actualiza la vista angular.

Sin embargo, hay una manera simple de cortocircuitar esto. Relojes angulares para un cambio de ubicación (ya sea que se realice escribiendo en la barra de direcciones, haciendo clic en un enlace o estableciendo la ubicación a través de $location.path() ). Cuando detecta este cambio, transmite un evento, $locationChangeSuccess , y comienza el proceso de enrutamiento. Lo que hacemos es capturar el evento y restablecer la ruta a lo que era anteriormente.

 function MyCtrl($route, $scope) { var lastRoute = $route.current; $scope.$on('$locationChangeSuccess', function(event) { $route.current = lastRoute; }); } 

Mi solución fue usar $ routeChangeStart porque eso le da las rutas “siguiente” y “última”, puede compararlas sin la necesidad de una variable adicional como en $ locationChangeSuccess.

El beneficio es poder acceder a la propiedad “params” en las rutas “siguiente” y “última” como next.params.yourproperty cuando está utilizando el estilo de URL “/ property / value” y, por supuesto, use $location.url o $location.path para cambiar la URL en lugar de $location.search() que depende de “? property = value” URL style.

En mi caso, lo utilicé no solo para eso sino también para evitar que la ruta cambie, el controlador no cambió:

 $scope.$on('$routeChangeStart',function(e,next,last){ if(next.$$route.controller === last.$$route.controller){ e.preventDefault(); $route.current = last.$$route; //do whatever you want in here! } }); 

Personalmente, creo que AngularJS debería proporcionar una forma de controlarlo, en este momento suponen que cada vez que cambie la ubicación del navegador, quiere cambiar la ruta.

Debería estar cargando $location mediante Dependency Injection y utilizando lo siguiente:

 $scope.apply(function () { $location.path("yourPath"); } 

Tenga en cuenta que no debe usar hashtags (#) mientras usa $location.path . Esto es por compatibilidad para el modo HTML5.

El evento $ locationChangeSuccess es un poco de un enfoque de fuerza bruta, pero descubrí que verificando la ruta nos permite evitar recargas de página cuando la plantilla de ruta de ruta no se modifica, pero vuelve a cargar la página cuando se cambia a una plantilla de ruta diferente:

 var lastRoute = $route.current; $scope.$on('$locationChangeSuccess', function (event) { if (lastRoute.$$route.originalPath === $route.current.$$route.originalPath) { $route.current = lastRoute; } }); 

Agregar ese código a un controlador en particular hace que la recarga sea más inteligente.

Editar: Si bien esto hace que sea un poco más fácil, en última instancia, no me gustó la complejidad del código que estaba escribiendo para mantener la apariencia amigable de las URL. Al final, acabo de cambiar a un parámetro de búsqueda y angular maneja mucho mejor.

Necesitaba hacer esto, pero después de preocuparme por tratar de obtener los eventos $locationChange~ para que funcione, supe que puedes hacer esto en la route usando resolve .

 $routeProvider.when( '/page', { templateUrl : 'partial.html', controller : 'PageCtrl', resolve : { load : ['$q', function($q) { var defer = $q.defer(); if (/*you only changed the idea thingo*/) //dont reload the view defer.reject(''); //otherwise, load the view else defer.resolve(); return defer.promise; }] } } );