Chcę obserwować zmiany w słowniku, ale z jakiegoś powodu funkcja oddzwaniania nie jest wywoływana.
Oto kontroler, którego używam:
function MyController($scope) {
$scope.form = {
name: 'my name',
surname: 'surname'
}
$scope.$watch('form', function(newVal, oldVal){
console.log('changed');
});
}
Oto skrzypce .
Oczekuję, że oddzwanianie $ watch będzie uruchamiane przy każdej zmianie imienia lub nazwiska, ale tak się nie dzieje.
Jaki jest właściwy sposób to zrobić?
javascript
angularjs
angularjs-scope
Vladimir Sidorenko
źródło
źródło
Odpowiedzi:
Zadzwoń
$watch
ztrue
jako trzeci argument:Domyślnie podczas porównywania dwóch złożonych obiektów w JavaScript, będą sprawdzane pod kątem równości „referencyjnej”, która pyta, czy dwa obiekty odnoszą się do tej samej rzeczy, a nie równości „wartościowej”, która sprawdza, czy wartości wszystkich właściwości tych właściwości obiekty są równe.
Zgodnie z dokumentacją Angular trzeci parametr dotyczy
objectEquality
:źródło
true
, sprawdzi równość odniesienia, jeśli obserwowana wartość jest obiektem lub tablicą. W takim przypadku należy jawnie określić właściwości, takie jak$scope.$watch('form.name')
i$scope.$watch('form.surname')
form
Obiekt nie zmienia, tylkoname
właściwość jestzaktualizowane skrzypce
źródło
Mała wskazówka dotycząca wydajności, jeśli ktoś ma usługę magazynu danych z kluczem -> parami wartości:
Jeśli masz usługę o nazwie dataStore , możesz aktualizować znacznik czasu za każdym razem, gdy zmienia się Twój obiekt big data. W ten sposób zamiast głębokiego oglądania całego obiektu, obserwujesz jedynie znacznik czasu dla zmiany.
W dyrektywie obserwujesz tylko znacznik czasu, który chcesz zmienić
źródło
newVal
,oldVal
w tym przykładzie są wartościami datownika, a nie wartościami obserwowanych obiektów. To nie unieważnia tej odpowiedzi, myślę tylko, że jest to wada, o której warto wspomnieć.Przyczyną tego, że Twój kod nie działa, jest
$watch
domyślnie sprawdzanie referencji. Krótko mówiąc, upewnij się, że obiekt, który jest do niej przekazywany, jest nowym obiektem. Ale w twoim przypadku modyfikujesz tylko niektóre właściwości obiektu formularza, a nie tworzysz nową. Aby działało, możesz podaćtrue
jako trzeci parametr.Będzie działać, ale możesz użyć $ watchCollection, który będzie bardziej wydajny niż $ watch, ponieważ
$watchCollection
będzie szukał płytkich właściwości na obiekcie formularza. Na przykładźródło
Gdy szukasz zmian obiektów formularza, najlepiej zastosować podejście obserwacyjne
$watchCollection
. Zapoznaj się z oficjalną dokumentacją różnych cech wydajności.źródło
Spróbuj tego:
źródło
Dla każdego, kto chce obserwować zmianę obiektu w obrębie szeregu obiektów, wydaje mi się, że to działa dla mnie (podobnie jak inne rozwiązania na tej stronie):
źródło
źródło