当前位置:  开发笔记 > 前端 > 正文

如何在Angular中观察表单更改

如何解决《如何在Angular中观察表单更改》经验,为你挑选了3个好方法。

在Angular中,我可能有一个看起来像这样的表单:


    
    

    
    

在相应的控制器中,我可以轻松地观察对该表单内容的更改,如下所示:

function($scope) {

    $scope.model = {};

    $scope.$watch('model', () => {
        // Model has updated
    }, true);

}

这是JSFiddle上的一个Angular示例.

我无法弄清楚如何在Angular中完成同样的事情.显然,我们不再拥有$scope$ rootScope.当然有一种方法可以实现同样的目的吗?

这是一个关于Plunker的Angular示例.



1> dfsq..:

UPD.更新答案和演示以与最新的Angular保持一致.


您可以订阅整个表单更改,因为表示表单的FormGroup提供了一个ObservrablevalueChanges实例的属性:

this.form.valueChanges.subscribe(data => console.log('Form changes', data));

在这种情况下,您需要使用FormBuilder手动构造表单.像这样的东西:

export class App {
  constructor(private formBuilder: FormBuilder) {
    this.form = formBuilder.group({
      firstName: 'Thomas',
      lastName: 'Mann'
    })

    this.form.valueChanges.subscribe(data => {
      console.log('Form changes', data)
      this.output = data
    })
  }
}

查看valueChanges演示中的操作:http://plnkr.co/edit/xOz5xaQyMlRzSrgtt7Wn?p = preview


这非常接近标志.要确认 - 你是否告诉我,*不可能订阅表单的`valueChanges`事件发射器*如果*该表单仅在模板中定义?换句话说 - 在组件的构造函数中,是否不可能获得对仅在该组件模板中定义的表单的引用,而不是在FormBuilder的帮助下?
@tambler,你可以使用`@ViewChild()`来获得对NgForm的引用.看到我更新的答案.

2> Mark Rajcok..:

如果您正在使用FormBuilder,请参阅@ dfsq的答案.

如果您不使用FormBuilder,有两种方法可以通知更改.

方法1

正如对问题的评论中所讨论的,在每个输入元素上使用事件绑定.添加到您的模板:


然后在你的组件中:

doSomething(newValue) {
  model.first_name = newValue;
  console.log(newValue)
}

" 表单"页面提供了一些与此相关的ngModel的其他信息:

ngModelChange不是元素事件.它实际上是NgModel指令的事件属性.当Angular在表单中看到绑定目标时[(x)],它期望该x指令具有x输入属性和xChange输出属性.

另一个奇怪的是模板表达,model.name = $event.我们习惯于看到$event来自DOM事件的对象.ngModelChange属性不会生成DOM事件; 它是一个Angular EventEmitter属性,在它触发时返回输入框值.

我们几乎总是喜欢[(ngModel)].如果我们必须在事件处理中执行一些特殊操作(例如去抖动或限制击键),我们可能会拆分绑定.

在你的情况下,我想你想做一些特别的事情.

方法2

定义本地模板变量并将其设置为ngForm.
在输入元素上使用ngControl.
使用@ViewChild获取对表单的NgForm指令的引用,然后订阅NgForm的ControlGroup以进行更改:

.... ... class MyForm { @ViewChild('myForm') form; ... ngAfterViewInit() { console.log(this.form) this.form.control.valueChanges .subscribe(values => this.doSomething(values)); } doSomething(values) { console.log(values); } }

plunker

有关方法2的更多信息,请参阅Savkin的视频.

另请参阅@ Thierry的答案,了解有关使用valueChangesobservable 可以执行的操作的更多信息(例如在处理更改之前稍微进行去抖/等待).



3> Thierry Temp..:

要完成更多以前的优秀答案,您需要注意表单利用observable来检测和处理值更改.这是非常重要和强大的东西.Mark和dfsq都在他们的答案中描述了这个方面.

Observable不仅允许使用该subscribe方法(类似于thenAngular 1中的promise方法).如果需要,您可以进一步实现表单中更新数据的某些处理链.

我的意思是你可以在这个级别指定debounceTime方法的去抖时间.这允许您在处理更改之前等待一段时间并正确处理多个输入:

this.form.valueChanges
    .debounceTime(500)
    .subscribe(data => console.log('form changes', data));

您还可以在更新值时直接插入要触发的处理(例如,某些异步处理).例如,如果要处理文本值以根据AJAX请求筛选列表,可以使用以下switchMap方法:

this.textValue.valueChanges
    .debounceTime(500)
    .switchMap(data => this.httpService.getListValues(data))
    .subscribe(data => console.log('new list values', data));

您甚至可以将返回的observable直接链接到组件的属性:

this.list = this.textValue.valueChanges
    .debounceTime(500)
    .switchMap(data => this.httpService.getListValues(data))
    .subscribe(data => console.log('new list values', data));

并使用async管道显示它:

  • {{elt.name}}

只是说你需要考虑在Angular2中以不同方式处理表单的方式(一种更强大的方式;-)).

希望它对你有帮助,蒂埃里

推荐阅读
wurtjq
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有