AngularJS: modeldeki değişikliği otomatik olarak algılar


103

Bir modelin değerleri her değiştiğinde bazı kodları otomatik olarak çalıştırmak gibi (verileri bir sunucuya kaydetmek gibi) yapmak istediğimi varsayalım. Bunu ng-change, modeli değiştirebilecek her bir kontrole benzer şekilde ayarlamanın tek yolu mudur ?

Yani, görünümlerle, açıkça herhangi bir şey bağlamak zorunda kalmadan model değiştikçe işler değişir. Bir sunucuya kaydeden kodu çalıştırmanın bir analogu var mı? Gibi bir şey

myModel.on('change', function() {
  $.post("/my-url", ...);
});

omurga gibi bir şeyle görebileceğiniz gibi.

Yanıtlar:


151

{{}}Ve / veya ng-modelli görünümlerde , Angular $watch()sizin için perde arkasında es ayarlıyor .

Varsayılan $watcholarak referansa göre karşılaştırır. Eğer üçüncü parametre ayarlarsanız $watchiçin true, Eğik yerine "sığ" değişiklikler için nesneyi seyredecek. Diziler için bu, dizi öğelerinin karşılaştırılması anlamına gelir; nesne eşlemeleri için bu, özelliklerin izlenmesi anlamına gelir. Yani bu istediğini yapmalı:

$scope.$watch('myModel', function() { ... }, true);

Güncelleme : Angular v1.2 bunun için yeni bir yöntem ekledi "$ watchCollection () :

$scope.$watchCollection('myModel', function() { ... });

Referansların takip edilmemesi nedeniyle "sığ" kelimesinin karşılaştırmayı açıklamak için "derin" yerine kullanıldığına dikkat edin - örneğin, izlenen nesne başka bir nesneye referans olan bir özellik değeri içeriyorsa, bu referans karşılaştırmak için izlenmez. diğer nesne.


1
Ah, harika! Bunun belgelenmiş gibi görünmemesinin herhangi bir nedeni var mı (yani, açısal sitedeki öğreticilerden hiçbirinin $ watch'u doğrudan ayarladığından bahsetmediğini düşünüyorum)? Bunda ng-change, girdi kontrollerinde (potansiyel olarak çoklu) kancalar kurmayı daha iyi bir fikir haline getirecek kötü bir şey var mı ?
Alec

12
Evet, ana eğitimde bir yerde $ watch'tan bahsedilse iyi olur. Bu yaklaşımla ilgili "kötü" olan şey, modelinizin büyük olması durumunda zaman alıcı olabilmesidir (her özet döngüsü - bir giriş alanındaki her tuş vuruşu - bu modelin derinlemesine kontrol edilmesine neden olur, muhtemelen birden çok kez) . Bu durumda, seçici $ watch () lar veya seçici ng-değişim daha iyi olacaktır.
Mark Rajcok

8

Form öğelerinizi durumuna göre (değiştirilmiş / değiştirilmemiş) dinamik olarak biçimlendirmeniz veya bazı değerlerin gerçekten değişip değişmediğini test etmeniz gerekirse, kendi geliştirdiğim şu modülü kullanabilirsiniz: https://github.com/betsol / açısal giriş değiştirilmiş

Forma ve onun alt öğelerine ek özellikler ve yöntemler ekler. Bununla, bazı öğelerin yeni veri içerip içermediğini test edebilir veya hatta tüm formda kaydedilmemiş yeni veriler olup olmadığını test edebilirsiniz.

Aşağıdaki saati kurabilirsiniz: $scope.$watch('myForm.modified', handler)ve bazı form öğeleri gerçekten yeni veriler içeriyorsa veya başlangıç ​​durumuna geri döndüyse, işleyiciniz çağrılacaktır.

Ayrıca, modifiedAJAX çağrısı aracılığıyla bir sunucuya gönderilen veri miktarını gerçekten azaltmak için tek tek form öğelerinin özelliğini kullanabilirsiniz . Değiştirilmemiş verilerin gönderilmesine gerek yoktur.

Bonus olarak, forma çağrı reset()yöntemiyle formunuzu başlangıç ​​durumuna geri döndürebilirsiniz .

Modül demosunu burada bulabilirsiniz: http://plnkr.co/edit/g2MDXv81OOBuGo6ORvdt?p=preview

Şerefe!


Bunu kontrolörde kontrol etmenin bir yolu var mı? örneğin, x düğmesine tıklarsanız, if (myform.modified) şov onay açılır penceresini beğenebilir miyim?
Flash

Elbette, FormController'ı denetleyicinizin işlevine iletin: <form name="myForm">, <button ng-click="vm.doSomething(myForm)">.
Slava Fomin II

teşekkürler, bu sadece form doğru değiştirilmişse bir şeyler yapacak mı?
Flash

Bu geçecek FormControllerkadar doSomething()kontrolörünüzün fonksiyonu. Bu işlevin içinde onunla istediğiniz her şeyi yapabilirsiniz, örneğin FormController.modifiedboole özelliğini kontrol ederek formun gerçekten değiştirilip değiştirilmediğini kontrol edebilirsiniz .
Slava Fomin II

Teşekkürler! Güzel Özellik
Flash
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.