AngularJS: $ scope. $ Watch nie aktualizuje wartości pobranej z $ resource w dyrektywie niestandardowej
Mam problem z niestandardowymi dyrektywami, które doprowadzają mnie do szału. Próbuję utworzyć następującą dyrektywę niestandardową (atrybut):
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);
});
}
}
});
Ta dyrektywa „typu atrybutu” (tzw. SeatMap) próbuje wyświetlić listę identyfikatorów miejsc (np. Dla teatru), które pobiorę z serwera za pośrednictwem usługi $ resource (patrz kod poniżej) do elementu div (elementu) .
Używam go z tym prostym, częściowym HTML:
<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>
I to jest kontroler, który ładuje zakres:
function SeatsCtrl($scope, Seats) {
$scope.sessionId = "12345";
$scope.zoneId = "A";
$scope.seats = Seats.query({sessionId: $scope.sessionId, zoneId: $scope.zoneId});
$scope.max_seats = 4;
}
Gdzie „Miejsca” to prosta usługa wykorzystująca zasoby $ do pobrania JSON z serwera
angular.module('myApp.services', ['ngResource'])
.factory('Seats', function($resource){
return $resource('json/seats-:sessionId-:zoneId.json', {}, {});
})
;
app.js (asientos_libres.html to część, z której korzystałem):
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'});
}]);
Problem polega na tym, że chociaż ustawiłem „zakres. $ Watch” w funkcji łącza dyrektywy, aby zakres mógł sprawdzić, czy atrybut „siedzenia” zmienił się w celu zaktualizowania listy identyfikatorów, to nie działa w moment $ scope.seats zmienia się w kontrolerze (gdy wywołujemy „zapytanie”).
Jak widać w kodzie, spróbowałem użyć $ timeout, aby opóźnić uruchomienie „updateSeatInfo”, ale obawiam się, że zdecydowanie nie jest to najmądrzejsze rozwiązanie ...
Próbowałem też nie tworzyć żądania JSON, ale używam sztywnego słownika w $ scope.seats i działa, więc wydaje się, że jest to kwestia synchronizacji.
Uwaga: updateSeatInfo to po prostu funkcja testowa, rzeczywista funkcja, której użyję, jest nieco bardziej skomplikowana.
Masz jakiś pomysł, jak sobie z tym poradzić?
Z góry dziękuję!
Edytuj 1: Dodano app.js, gdzie używam routera do wywołania SeatsCtrl, dzięki Supr za radę. Jednak nadal mam ten sam problem.
Edytuj 2: Rozwiązany! (?) Dobrze! Wygląda na to, że znalazłem rozwiązanie, które może nie być najlepsze, ale działa poprawnie! :) O ile mogłem tu zobaczyćhttp://docs.angularjs.org/api/ng.$timeout, możemy użyć $ timeout (wrapper na setTimeout)bez opóźnienia! Jest to świetne, ponieważ nie sztucznie opóźniamy wykonanie naszego kodu wewnątrz $ timeout, ale nakazujemy, aby dyrektywa nie uruchamiała go, dopóki nie zakończy się żądanie asynchroniczne.
Mam nadzieję, że zadziała również w przypadku żądań o długim oczekiwaniu ...
Jeśli ktoś wie, jak to naprawić, powiedz!