在AngularJS中,我可能有一个看起来像这样的表单:
<ng-form>
<label>First Name</label>
<input type="text" ng-model="model.first_name">
<label>Last Name</label>
<input type="text" ng-model="model.last_name">
</ng-form>
在相应的控制器中,我可以轻松地观察对该表单内容的更改,如下所示:
function($scope) {
$scope.model = {};
$scope.$watch('model', () => {
// Model has updated
}, true);
}
这是AngularJS example on JSFiddle .
我无法弄清楚如何在Angular中完成同样的事情 . 显然,我们不再有 $scope
等......但是肯定有一种方法可以实现同样的目的吗?
6 回答
UPD . 更新答案和演示以与最新的Angular保持一致 .
您可以订阅整个表单更改,因为表示表单的FormGroup提供了
valueChanges
属性,这是一个Observerable实例:在这种情况下,您需要使用FormBuilder手动构造表单 . 像这样的东西:
查看 demo 中的
valueChanges
:http://plnkr.co/edit/xOz5xaQyMlRzSrgtt7Wn?p=preview如果您使用
FormBuilder
,请参阅@ dfsq的答案 .如果您未使用
FormBuilder
,则有两种方法可以通知更改 .Method 1
正如对该问题的评论中所讨论的,在每个输入元素上使用event binding . 添加到您的模板:
然后在你的组件中:
Forms页面提供了一些与此相关的ngModel的其他信息:
在你的情况下,我想你想做一些特别的事情 .
Method 2
定义本地模板变量并将其设置为
ngForm
.在输入元素上使用ngControl .
获取对表单's NgForm directive using @ViewChild, then subscribe to the NgForm'的ControlGroup的引用以进行更改:
plunker
有关方法2的更多信息,请参见Savkin's video .
另请参阅@ Thierry的答案,了解有关使用
valueChanges
observable可以执行的操作的更多信息(例如在处理更改之前稍微进行去抖/等待) .要完成更多以前的优秀答案,您需要注意表单利用observable来检测和处理值更改 . 这是非常重要和强大的东西 . Mark和dfsq都在他们的答案中描述了这个方面 .
Observable不仅允许使用
subscribe
方法(类似于Angular 1中的承诺的then
方法) . 如果需要,您可以进一步实现表单中更新数据的某些处理链 .我的意思是您可以使用
debounceTime
方法在此级别指定去抖时间 . 这允许您在处理更改之前等待一段时间并正确处理多个输入:您还可以在更新值时直接插入要触发的处理(例如,某些异步处理) . 例如,如果要处理文本值以根据AJAX请求筛选列表,则可以使用
switchMap
方法:您甚至可以将返回的observable直接链接到组件的属性:
并使用
async
管道显示它:只是说你需要考虑在Angular2中以不同方式处理表单的方式(一种更强大的方式;-)) .
希望它对你有帮助,蒂埃里
扩展Mark的建议......
Method 3
在模型上实施"deep"更改检测 . 优点主要涉及避免将用户界面方面结合到组件中;这也捕获了对模型进行的程序化更改 . 也就是说,如Thierry所建议的那样,需要额外的工作来实现诸如去抖动之类的东西,这也会引起程序化的变化,因此请谨慎使用 .
Try in Plunker
我考虑使用(ngModelChange)方法,然后考虑了FormBuilder方法,最后确定了方法3的变体 . 这样可以节省使用额外属性装饰模板并自动获取模型的更改 - 使用方法1或2减少遗忘的可能性 .
稍微简化方法3 ......
您可以添加超时,仅在x毫秒后调用doSomething()来模拟去抖动 .
对于角
5+
版本 . 放置版本有助于角度进行大量更改 .