Tengo un problema con las directivas personalizadas que me está volviendo loco. estoy tratando de crear el siguiente encargo (atributo) Directiva:
angular.module('componentes', [])
.directive("seatMap", function(){
return {
restrict: 'A',
link: function(scope, element, attrs, controller){
function updateSeatInfo(scope, element){
var txt = "";
for (var i in scope.seats)
txt = txt + scope.seats[i].id + " ";
$(element).text("seat ids: "+txt);
}
/*
// This is working, but it's kind of dirty...
$timeout(function(){updateSeatInfo(scope,element);}, 1000);
*/
scope.$watch('seats', function(newval, oldval){
console.log(newval, oldval);
updateSeatInfo(scope,element);
});
}
}
});
Esta directiva "de tipo atributo" (llamado Mapa de asientos) está tratando de mostrar una lista de identificadores de seguridad (por ejemplo, para un teatro), que Lo buscaré desde el servidor a través del servicio $ resource (ver el código a continuación) en un div (elemento).
lo estoy usando con esta simple html parcial:
<div>
<!-- This is actually working -->
<ul>
<li ng-repeat="seat in seats">{{seat.id}}</li>
</ul>
<!-- This is not... -->
<div style="border: 1px dotted black" seat-map></div>
</div>
y este es el controlador que está cargando al alcance:
function SeatsCtrl($scope, Seats) {
$scope.sessionId = "12345";
$scope.zoneId = "A";
$scope.seats = Seats.query({sessionId: $scope.sessionId, zoneId: $scope.zoneId});
$scope.max_seats = 4;
}
Donde "Asientos" es un servicio sencillo usando $ recursos en busca de un JSON desde el servidor
angular.module('myApp.services', ['ngResource'])
.factory('Seats', function($resource){
return $resource('json/seats-:sessionId-:zoneId.json', {}, {});
})
;
app.js (asientos_libres.html parcial es el que he b een el uso):
angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'componentes']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/view1', {templateUrl: 'partials/asientos_libres.html', controller: SeatsCtrl});
$routeProvider.otherwise({redirectTo: '/view1'});
}]);
El problema es, a pesar de que he creado un "alcance $ reloj." en la función de enlace de la Directiva por lo que el alcance puede comprobar si "asientos" atributo ha cambiado para actualizar el lista de identificadores, no está funcionando en este momento $ scope.seats está cambiando en el controlador (cuando llamamos "consulta").
Como se puede ver en el código, he hecho un intento usando $ tiempo de espera para retrasar el lanzamiento de "updateSeatInfo", pero me temo que no es la solución más inteligente, con mucho, ...
También probé para no hacer una solicitud JSON, pero use un diccionario codificado en $ scope.seats y funciona, por lo que parece que es una cuestión de sincronía.
Nota: UpdateSeatInfo es solo una función de prueba, la función real que usaré es un poco más compleja.
¿Alguna idea sobre cómo lidiar con eso?
¡Muchas gracias de antemano!
Edit 1: App.js agregada, donde estoy usando enrutador para llamar a SeatsCtrl, gracias a Supr por el consejo. Sin embargo, sigo teniendo el mismo problema.
Editar 2: Resuelto! (?) Ok! Parece que encontré una solución, que puede no ser la mejor, ¡pero funciona correctamente! :) Por lo que pude ver aquí http://docs.angularjs.org/api/ng.$timeout, podemos usar $ timeout (un contenedor sobre setTimeout) sin demora! Esto es genial porque no estamos retrasando artificialmente la ejecución de nuestro código dentro de $ timeout, pero estamos haciendo que la directiva no lo ejecute hasta que la solicitud asíncrona haya finalizado.
esperanza de que va a trabajar para las solicitudes largo de espera, también ...
Si alguien sabe una mejor manera de solucionarlo, por favor diga!
Una palabra de advertencia: las comparaciones profundas como esta tienen un costo de rendimiento. En su mayor parte es un problema cuando se observa una colección de objetos en lugar de un solo objeto, pero vale la pena tenerlo en cuenta. –