Czy można ustawić $watch
na tablicy obiektów wewnątrz usługi (chciałbym, aby deklaracja $watch
była wewnątrz usługi)?
Odpowiedz
Możesz dodać dowolne wyrażenie do zestawu zegarów, wstrzykując $rootScope
i używając funkcji pierwszy argument metody $watch
. Pseudo-kod:
$rootScope.$watch(function() {
return //value to be watched;
}, function watchCallback(newValue, oldValue) {
//react on value change here
});
Nie zapomnieć o trzecim, logicznego argumentu metody $watch
. Musisz podać wartość true
, jeśli chcesz dokładnie obejrzeć cały obiekt w celu wprowadzenia zmian.
usługi z natury są jak zajęcia i metody domowe. Można skonfigurować metodę, która nawiązywać połączenia z kontrolerem który jest argumentem jest zakres i zastosowanie wyrażenia Watch:
app.service('myservice',function(){
this.listen = function($scope) {
$scope.$watch(function(){return someScopeValue},function(){
//$scope.dosomestuff();
});
}
});
//your controller
function myCtrl($scope,myservice) {
$scope.listen = function() {
myservice.listen($scope);
}
//call your method
$scope.listen();
}
aktualizacji: Jeśli próbujesz oglądać prywatną zmienną lokalną wewnątrz serwisu, patrz akceptowane odpowiedz za pomocą $ rootScope. Jeśli próbujesz $ oglądać zmienną $ scope w zasięgu lokalnym, to powyższe jest najlepszym rozwiązaniem. Osiągają dwie bardzo różne rzeczy.
To może wydawać się głupim pytaniem, ale dlaczego umieszczasz 'myservice.listen ($ scope)' wewnątrz funkcji? Czy to jest łatwe do ponownego użycia w całym kodzie, czy jest jakiś ważny powód? Poza tym, jeśli postawię zegarek $ w fabryce, czy nadal będzie działać? –
Czy możesz wyjaśnić, co chcesz osiągnąć? Jak rozumiem, otrzymujesz tablicę obiektów z serwera jako model. To nie jest jasne:
- Chcesz sprawdzić, czy niektóre obiekty w tablicy zostały zmienione (być może od czasu ostatniego połączenia z serwerem w przypadku robisz nawracające pooling)?
- Czy chcesz sprawdzić, czy niektóre obiekty w tablicy zostały zmienione przez użytkownika za pomocą niektórych elementów kontrolnych na przednim panelu?
W przypadku 1, tak naprawdę nie trzeba używać $ watch (lub raczej $ watchCollection), ale powinieneś iterować przez tablicę otrzymaną od serwera i zweryfikować zmiany (dokładnie to, co zrobiłby $ watchColleciton). W przypadku, gdy obiekt jest inny od tego, który aktualnie posiadasz - wywołujesz obiekt. $ Save() na tym elemencie.
W przypadku 2, użyj $ watchCollection() na $ scope przekazanym jako parametr do funkcji usługi lub użyj $ rootScope, jeśli przechowujesz swoją tablicę w $ rootScope.
Mogę podać ci prawdziwy kod, jeśli chcesz wyjaśnić scenariusze.
Po prostu miałem sytuację, w której miałem dość duży układ zegarka na dwóch różnych kontrolerach.
Ponieważ nie chciałam powielać kodu Właśnie zdefiniowany funkcjonować w mojej służbie:
angular
.module('invoice')
.factory('invoiceState', function() {
var invoice = {
client_info: {
lastname: "",
firstname: "",
email: "",
phone: "",
id_client: "",
...
}
}
invoice.watchAccommodation = function (newVal, oldVal) {
var accommodation = newVal;
//Whatever you would normally have in your watch function
}
Następnie można po prostu wywołać tę funkcję w zegarku każdego kontrolera do którego wtryskiwanego usługę
function NewInvoiceCtrl(invoiceState) {
$scope.$watch('invoice.accommodation',invoiceState.watchAccommodation, true);
}
nie mam dużego doświadczenia z angularjs tak naprawdę nie mogę iść do aspektów skuteczności tego podejścia, ale to działa;)
jeśli nie masz nic przeciwko, chciałbym Ci sho w jaki sposób odwołujesz się do zwracanej wartości usługi z pierwszej funkcji. Starałem się jak mogłem, ale nie udało mi się obserwować zmian.Ta sama wartość była nieustannie zwracana w kółko. – Birowsky
@Birowsky Czy próbowałeś '$ watchCollection'? –
To nie pomaga, ponieważ ogląda rootScope dla całej aplikacji. – btm1