AngularJS:自动检测模型的变化


103

假设我想做一些事情,只要模型的值发生更改,就可以自动运行一些代码(例如将数据保存到服务器)。通过ng-change在每个控件上设置可能会更改模型的内容来做到这一点的唯一方法是吗?

即,使用视图,事情随着模型的改变而正确地改变,而不必明确地挂钩任何东西。是否存在可以运行保存到服务器的代码的类似物?就像是

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

就像您可能会看到像骨干一样。

Answers:


151

在具有{{}}和/或ng模型的视图中,Angular $watch()在幕后为您设置es。

默认情况下$watch按引用进行比较。如果将第三个参数设置$watchtrue,则Angular会“浅”监视对象的更改。对于数组,这意味着比较数组项,对于对象映射,这意味着观察属性。所以这应该做你想要的:

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

更新:Angular v1.2为此添加了一个新方法,`$ watchCollection()

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

请注意,“浅”一词用于描述比较,而不是“深”,因为未遵循引用-例如,如果监视的对象包含作为对另一对象的引用的属性值,则不遵循该引用来进行比较另一个对象。


1
啊,太好了!是否有任何原因似乎没有记录在案(即我不认为在角度站点上的任何教程都提到直接设置$ watches)?有什么不好的办法可以使ng-change在输入控件上设置(可能多个)钩子更好的主意吗?
亚历克

12
是的,如果主教程在某处提到$ watch会很好。这种方法的“坏处”是,如果您的模型很大,则可能会很费时(每个摘要周期-输入字段中的每个击键-都会导致对该模型进行深入的脏检查,可能会多次) 。在这种情况下,选择性$ watch()es或选择性ng-change会更好。
Mark Rajcok

8

并且,如果您需要根据状态(修改/未修改)动态地设置表单元素的样式或测试某些值是否实际上已更改,则可以使用由我自己开发的以下模块:https : //github.com/betsol /角度输入修改

它向表单及其子元素添加了其他属性和方法。使用它,您可以测试某个元素是否包含新数据,甚至可以测试整个表单是否具有新的未保存数据。

您可以设置以下监视:$scope.$watch('myForm.modified', handler)如果某些表单元素实际上包含新数据或它恢复为初始状态,则将调用处理程序。

另外,您可以使用modified单个表单元素的属性来实际减少通过AJAX调用发送到服务器的数据量。无需发送不变的数据。

另外,您可以通过调用表单的reset()方法将表单恢复为初始状态。

您可以在此处找到该模块的演示:http : //plnkr.co/edit/g2MDXv81OOBuGo6ORvdt?p=preview

干杯!


有没有一种方法可以在控制器中进行检查。例如,如果单击x按钮,我可以像if(myform.modified)显示确认弹出窗口一样吗?
Flash

当然,只需将FormController传递给控制器​​的函数:<form name="myForm"><button ng-click="vm.doSomething(myForm)">
Slava Fomin II

谢谢,这只会在表格正确修改的情况下起作用吗?
Flash

这将传递FormControllerdoSomething()控制器的功能。您可以在该函数内部执行任何所需的操作,例如,通过检查FormController.modifiedboolean属性来检查表单是否被实际修改。
Slava Fomin II

谢谢!不错的功能
闪光
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.