在Angular中,我可能有一个看起来像这样的表单:
<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>
Run Code Online (Sandbox Code Playgroud)
在相应的控制器中,我可以轻松地观察对该表单内容的更改,如下所示:
function($scope) {
$scope.model = {};
$scope.$watch('model', () => {
// Model has updated
}, true);
}
Run Code Online (Sandbox Code Playgroud)
这是JSFiddle上的一个Angular示例.
我无法弄清楚如何在Angular中完成同样的事情.显然,我们不再拥有$scope$ rootScope.当然有一种方法可以实现同样的目的吗?
dfs*_*fsq 180
UPD.更新答案和演示以与最新的Angular保持一致.
您可以订阅整个表单更改,因为表示表单的FormGroup提供了一个ObservrablevalueChanges实例的属性:
this.form.valueChanges.subscribe(data => console.log('Form changes', data));
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您需要使用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
})
}
}
Run Code Online (Sandbox Code Playgroud)
查看valueChanges此演示中的操作:http://plnkr.co/edit/xOz5xaQyMlRzSrgtt7Wn?p = preview
Mar*_*cok 107
如果您正在使用FormBuilder,请参阅@ dfsq的答案.
如果您不使用FormBuilder,有两种方法可以通知更改.
方法1
正如对问题的评论中所讨论的,在每个输入元素上使用事件绑定.添加到您的模板:
<input type="text" class="form-control" required [ngModel]="model.first_name"
(ngModelChange)="doSomething($event)">
Run Code Online (Sandbox Code Playgroud)
然后在你的组件中:
doSomething(newValue) {
model.first_name = newValue;
console.log(newValue)
}
Run Code Online (Sandbox Code Playgroud)
" 表单"页面提供了一些与此相关的ngModel的其他信息:
这
ngModelChange不是<input>元素事件.它实际上是NgModel指令的事件属性.当Angular在表单中看到绑定目标时[(x)],它期望该x指令具有x输入属性和xChange输出属性.另一个奇怪的是模板表达,
model.name = $event.我们习惯于看到$event来自DOM事件的对象.ngModelChange属性不会生成DOM事件; 它是一个AngularEventEmitter属性,在它触发时返回输入框值.我们几乎总是喜欢
[(ngModel)].如果我们必须在事件处理中执行一些特殊操作(例如去抖动或限制击键),我们可能会拆分绑定.
在你的情况下,我想你想做一些特别的事情.
方法2
定义本地模板变量并将其设置为ngForm.
在输入元素上使用ngControl.
使用@ViewChild获取对表单的NgForm指令的引用,然后订阅NgForm的ControlGroup以进行更改:
<form #myForm="ngForm" (ngSubmit)="onSubmit()">
....
<input type="text" ngControl="firstName" class="form-control"
required [(ngModel)]="model.first_name">
...
<input type="text" ngControl="lastName" class="form-control"
required [(ngModel)]="model.last_name">
class MyForm {
@ViewChild('myForm') form;
...
ngAfterViewInit() {
console.log(this.form)
this.form.control.valueChanges
.subscribe(values => this.doSomething(values));
}
doSomething(values) {
console.log(values);
}
}
Run Code Online (Sandbox Code Playgroud)
有关方法2的更多信息,请参阅Savkin的视频.
另请参阅@ Thierry的答案,了解有关使用valueChangesobservable 可以执行的操作的更多信息(例如在处理更改之前稍微进行去抖/等待).
Thi*_*ier 61
要完成更多以前的优秀答案,您需要注意表单利用observable来检测和处理值更改.这是非常重要和强大的东西.Mark和dfsq都在他们的答案中描述了这个方面.
Observable不仅允许使用该subscribe方法(类似于thenAngular 1中的promise方法).如果需要,您可以进一步实现表单中更新数据的某些处理链.
我的意思是你可以在这个级别指定debounceTime方法的去抖时间.这允许您在处理更改之前等待一段时间并正确处理多个输入:
this.form.valueChanges
.debounceTime(500)
.subscribe(data => console.log('form changes', data));
Run Code Online (Sandbox Code Playgroud)
您还可以在更新值时直接插入要触发的处理(例如,某些异步处理).例如,如果要处理文本值以根据AJAX请求筛选列表,可以使用以下switchMap方法:
this.textValue.valueChanges
.debounceTime(500)
.switchMap(data => this.httpService.getListValues(data))
.subscribe(data => console.log('new list values', data));
Run Code Online (Sandbox Code Playgroud)
您甚至可以将返回的observable直接链接到组件的属性:
this.list = this.textValue.valueChanges
.debounceTime(500)
.switchMap(data => this.httpService.getListValues(data))
.subscribe(data => console.log('new list values', data));
Run Code Online (Sandbox Code Playgroud)
并使用async管道显示它:
<ul>
<li *ngFor="#elt of (list | async)">{{elt.name}}</li>
</ul>
Run Code Online (Sandbox Code Playgroud)
只是说你需要考虑在Angular2中以不同方式处理表单的方式(一种更强大的方式;-)).
希望它对你有帮助,蒂埃里
| 归档时间: |
|
| 查看次数: |
118499 次 |
| 最近记录: |