Soru angularjs $ eski değeri ve yeni değeri aynıdır


Amacım bir modeli kapsam dahilinde izlemek ve eski değer ile yeni değer arasındaki farkı bulmaktır.

Ancak, eski değeri buldum ve yeni değer hepsi aşağıdaki koddan aynı.

app.controller('MyCtrl', function($scope, $timeout){
  $scope.markers = {};
  $scope.$watchCollection('markers', function(newValue, oldValue){
    console.log('being watched oldValue:', oldValue, 'newValue:', newValue);
  });
  $timeout( function() {
    $scope.markers.foo = 1;
  }, 500);
  $timeout( function() {
    $scope.markers.bar = 2;
  }, 500);
});

çıktı:

being watched oldValue: Object {} newValue: Object {} script.js:6
being watched oldValue: Object {foo: 1} newValue: Object {foo: 1} script.js:6
being watched oldValue: Object {foo: 1, bar: 2} newValue: Object {foo: 1, bar: 2} 

Neden aynılar ve eğer kasıtlıysa, neden?

işte kod http://plnkr.co/edit/rfMCF4x6CmVVT957DPSS?p=preview 


25
2017-12-23 22:13


Menşei


Ya belgeler güncel değil ya da bir hatadır. newValue === oldValue devletler false bu yüzden bir böcek olduğunu düşünmeye eğilimliydim. - artur grzesiak
Bilinen bir hata olduğunu ortaya çıkarır: github.com/angular/angular.js/issues/2621 - KayakDave
$ WatchCollection'ın derin $ saatinin kısayolu olduğunu farz ettim. Öyle görünmüyor. - allenhwkim
Hayatımın on dakikası israf etti. Bu soru için teşekkürler, bana çok zaman kazandırdı. :) - fabspro


Cevaplar:


Kullanabilirsiniz $watch Bunun yerine, bu işe görünüyor. Nesnede bulunan tüm özellikleri de (eğer yaptığınız gibi) izlemek istiyorsanız, eklemeniz gerekir. true Saatin üçüncü parametresi olarak. Bu derin bir saat oluşturur.

İşte bir çalışma plunker.

JS:

app = angular.module('myApp',[]);

app.controller('MyCtrl', function($scope, $timeout){
  $scope.markers = {};
  $scope.$watch('markers', function(newValue, oldValue){
    console.log('being watched oldValue:', oldValue, 'newValue:', newValue);
  }, true);
  $timeout( function() {
    $scope.markers.foo = 1;
  }, 500);
  $timeout( function() {
    $scope.markers.bar = 2;
  }, 500);
});

35
2017-12-23 22:21



WatchCollection için belgeler şöyle diyor: "Sığ, bir nesnenin özelliklerini izler ve özelliklerden herhangi biri değiştiğinde yangın yapar (diziler için bu, dizi öğelerini izlemeyi gerektirir; nesne haritaları için, bu özelliklerin izlenmesini gerektirir).". Dolayısıyla bir nesnede watchCollection kullanılması doğrudur. - JB Nizet
@JBNizet Strange sonra, ben watchCollection için önce derin bir saat (gerçek ekleyerek) yapmaya çalıştım, ama işe yaramadı. Düzenli derin saat vardı. :) Cevabı düzenledim, bu yüzden ikisi arasında varsayım yapmıyorum. - Davin Tryon
JB, WatchCollection bozuk. Evet, özellikler değiştiğinde patlar, hayır, belgelerde belirtildiği gibi eski değerleri kaydetmek için kaydetmez. Bunun yerine, yeni verilerin bir kopyasını yeni ve ayrı bir nesnede alırsınız. github.com/angular/angular.js/issues/2621 - Noishe


Yeni ve eski değerin eşit olup olmadığını (değerler olarak) kontrol etmenin ve beklenmedik davranışlardan kaçınmak için bu işlemi atlamanın çok yararlı olduğunu anladım. Kullanabilirsiniz angular.equals bunu başarmak için. İşte bir örnek:

JS:

$scope.$watch('myObject', function(newValue, oldValue){
    if(angular.equals(newValue, oldValue)){
        return; // simply skip that
    }
});

12
2017-08-13 19:54





Bu bir böcek.

https://github.com/angular/angular.js/issues/2621

ve sabit değil gibi görünüyor.


5
2018-01-04 17:31



Şimdi düzeltildi: github.com/angular/angular.js/issues/2621#issuecomment-37981379 - Itchy


Değerler parametre olarak geçirilir

$scope.$watch('foo', function (newValue, oldValue) {
  // ...
}

1
2017-07-11 16:15