javascript - rutas - Angularjs: ¿Cómo mostrar el ícono de carga al usar ''resolver'' en $ routeProvider?
ngroute (6)
El sistema de enrutamiento para angular parece ser un poco limitado.
Esto lo resolvió para mí:
http://www.bennadel.com/blog/2420-Mapping-AngularJS-Routes-Onto-URL-Parameters-And-Client-Side-Events.htm
Además, acerca de los eventos que se disparan dos veces: si configura una ruta, haga un mapa a "a / b / c" angular automáticamente configura otra ruta, "a / b / c /" (con barra inclinada) para redirigir al primero (y viceversa), y ambos desencadenan eventos. Solo pruebo la presencia de parámetros de ruta.
En cuanto a la condición limitada del sistema de enrutamiento: existe esta atracción desde angular, para extender sus capacidades.
El siguiente código se lee a través de un servicio y muestra en la página web una lista de objetos ''página'' para una ''categoría de página'' específica (cadena). Utilizando la propiedad del objeto de resolución en $ routeProvider.when (), puedo posponer la actualización de la vista hasta que el nuevo valor esté listo.
Dos preguntas:
Cuando solicite una nueva lista de páginas, quiero mostrar un ícono de carga. ¿Cómo puedo detectar (de forma no hackosa) el evento cuando se inicia la lectura desde el servidor (y se debe mostrar el ícono de carga)? Supongo que podría hacer algo como $ (''. Pages-loading-icon''). Show () en el servicio, pero creo que también es demasiado dependiente de la interfaz gráfica puesto en el servicio.
Cuando el nuevo valor esté listo, me gustaría que lo viejo se desvanezca y que lo nuevo se desvanezca. ¿Cuál es la forma ''angular'' de hacer esto? Intenté hacerlo en el controlador utilizando $ watch, pero eso hace que se muestre el nuevo valor poco antes de que comience el fadeout.
El código:
app.js:
$routeProvider.when(''/:cat'', { templateUrl: ''partials/view.html'', controller: RouteCtrl, resolve: RouteCtrl.resolve});
controllers.js:
function RouteCtrl($scope, $routeParams, pages) {
$scope.params = $routeParams;
$scope.pages = pages;
}
RouteCtrl.resolve={
pages: function($routeParams, Pages){
if($routeParams.hasOwnProperty(''cat'')){
return Pages.query($routeParams.cat);
}
}
}
services.js: las últimas páginas leídas se almacenan en CurrentPages y su categoría en lastCat.
factory(''Pages'', function($resource, $q, $timeout){
return {
res: $resource(''jsonService/cat=:cat'', {}, {
query: {method:''GET'', params:{cat:''cat''}, isArray:true}
}),
lastCat: null,
currentPages: null,
query: function(cat) {
var res = this.res;
if(cat != this.lastCat){
var deferred = $q.defer();
var p = res.query({''cat'':cat}, function(){
deferred.resolve(p);
});
this.lastCat = cat;
this.currentPages = deferred.promise;
}
return this.currentPages;
}
};
})
view.html
<ul >
<li ng-repeat="page in pages">
<a href="#{{params.cat}}/{{page.slug}}">{{page.title}}</a>
</li>
</ul>
Me gusta el ''ng-show''
... Pero el ''ui-if''
del proyecto Angular UI es mejor en mi humilde opinión. Como eliminar el código HTML del DOM ...
<span ui-if = "isViewLoading"> loading the view... </span>
_mi
No estoy seguro de si esto funcionaría en su código ya que tiene $ integración de recursos. Pero puede valer la pena examinar eventos angulares: $routeChangeStart
y $routeChangeSuccess
.
en html:
<span ng-show="isViewLoading"> loading the view... </span>
en el controlador (que define el alcance del html anterior):
$scope.isViewLoading = false;
$scope.$on(''$routeChangeStart'', function() {
$scope.isViewLoading = true;
});
$scope.$on(''$routeChangeSuccess'', function() {
$scope.isViewLoading = false;
});
$scope.$on(''$routeChangeError'', function() {
$scope.isViewLoading = false;
});
Puede crear una directiva que se muestre en función de una transmisión que envíe antes y después de una llamada de servicio, que puede poner en $ rootScope. Por lo tanto, si llama a una fábrica para manejar las llamadas genéricas POST / GET, justo antes de la llamada puede llamar a una función en $ rootScope, como "$ rootScope.startLoading ()" y cuando finalice, llame a "$ rootScope". doneLoading () ", donde cada uno de estos métodos transmite un evento para que pueda retomar su directiva. Luego solo maneja tu directiva para atrapar los eventos, "scope. $ On" ("startLoading", func (... "y haz que inserte / muestre una plantilla de carga div en el DOM y corra, luego también tiene una trampa para hecho carga para eliminar / ocultarlo.
De esta forma, puede tener una buena superposición de carga general.
También puede usar la directiva ng-show. Simplemente verifique si su modelo está vacío y muestre un subconjunto de DOM así:
<!-- model not ready -->
<div style="width: 200" ng-show="lines == ''''">
<div class="progress progress-striped active">
<div class="bar" style="width: 0%;"></div>
</div>
</div>
<!-- your model code -->
<ul class="nav nav-tabs nav-stacked">
<li ng-repeat="line in lines">
{{line.Id}}
</li>
</ul>
$rootScope
usar $rootScope
porque la monitorización de $scope
un controlador está limitada al controlador, y sucede que está cambiando de una vista (un controlador) a otra vista (otro controlador). Por lo tanto, tendría sentido tener one-code-fit-all.
$rootScope.$on(''$stateChangeStart'',
function(event, toState, toParams, fromState, fromParams){ ... })
En esa función configure $rootScope.isLoadingState
que mostrará su indicador de carga.
Entonces usa
$rootScope.$on(''$stateChangeSuccess'',
function(event, toState, toParams, fromState, fromParams){ ... })
Para desarmar esa variable.
Referencia completa here