在Angular 2中订阅valueChanges的正确方法
我一直在Angular 2中处理反应表单和valueChanges
订阅。我不明白为什么某些形式的订阅似乎不被允许。在Angular 2中订阅valueChanges的正确方法
this.form.get('name').valueChanges /* <- doesn't work */
.do(changes => {
console.log('name has changed:', changes)
});
.subscribe();
this.form.get('title').valueChanges.subscribe(/* <- does work */
changes => console.log('title has changed:', changes)
);
This plunker重现问题(开放DevTools控制台看到错误):
ZoneAwareError {stack: "Error: Uncaught (in promise): TypeError: Cannot se…g.com/[email protected]/dist/zone.js:349:25) []", message: "Uncaught (in promise): TypeError: Cannot set prope…ore.umd.js:8486:93)↵ at Array.forEach (native)", originalStack: "Error: Uncaught (in promise): TypeError: Cannot se…ps://unpkg.com/[email protected]/dist/zone.js:349:25)", zoneAwareStack: "Error: Uncaught (in promise): TypeError: Cannot se…g.com/[email protected]/dist/zone.js:349:25) []", name: "Error"…}
在上述第一图案(与do
)不是非法确实?
这使您plunker工作:
- 在app.ts
import 'rxjs/add/operator/do';
- 删除分号之后。做语句添加此import语句
.do(changes => { console.log('name has changed:', changes) })
C omplete改变app.ts
import {Component, NgModule, OnInit} from '@angular/core'
import {BrowserModule } from '@angular/platform-browser'
import { FormGroup, FormBuilder, Validators, ReactiveFormsModule, FormsModule } from '@angular/forms';
import { Observable } from 'rxjs/Observable';
import { Subscription } from 'rxjs/Subscription';
import 'rxjs/add/operator/do';
@Component({
selector: 'my-app',
template: `
<form novalidate [formGroup]="form">
<div>
<select type="text" class="form-control" name="title" formControlName="title">
<option *ngFor="let title of titles" value="{{title}}">{{title}}</option>
</select>
</div>
<div>
<input type="text" class="form-control" name="name" formControlName="name">
</div>
<fieldset formGroupName="address">
<legend>Address</legend>
<input type="text" class="form-control" name="street" formControlName="street">
<input type="text" class="form-control" name="city" formControlName="city">
</fieldset>
</form>
`,
})
export class App implements OnInit {
private form: FormGroup;
private titles: string[] = ['Mr', 'Mrs', 'Ms'];
constructor(private fb: FormBuilder){
}
ngOnInit() {
this.form = this.fb.group({
title: 'Mr',
name: '',
address: this.fb.group({
street: '',
city: ''
})
});
this.form.get('name').valueChanges
.do(changes => {
console.log('name has changed:', changes)
})
.subscribe();
this.form.get('title').valueChanges.subscribe(
changes => console.log('title has changed:', changes)
);
this.form.get('address').valueChanges.subscribe(
changes => console.log('address has changed:', changes)
);
}
}
@NgModule({
imports: [ BrowserModule, FormsModule, ReactiveFormsModule ],
declarations: [ App ],
bootstrap: [ App ]
})
export class AppModule {}
另一种解决办法是使用“ngModelChange”事件在你的模板
更改此:
<input type="text" class="form-control" (ngModelChange)="doNameChange($event)" name="name" formControlName="name">
在您的组件,那么你处理你的更改事件:
doNameChange(event: any){
alert("change")
}
谢谢,但正如您所见,我确实知道处理这些更改的一种工作方式。问题的关键是为什么一个合法的模式似乎不起作用。 – user776686
你为什么要用“做”?如果您将功能从“do”移动到正在使用的订阅模块 – Karl
我也有这个问题。
我想在我的情况下做debounceTime,所以它没有解决我的需求。
我其实忘了订阅!
但我能得到价值变动激活也这样说:在角文档从这里
this.form.get('name').valueChanges.forEach(
(value) => {console.log(value);})
为什么'do'是非法的?您不需要,您可以将回调传递给'subscribe(...)'。 Plunker并没有为我运行(不知道为什么,有一段时间以来,因此无法调查) –
这正是我困惑的问题:为什么它会是非法的? Plunkr并不总是喜欢我 - 我正在用DevTools的错误更新我的帖子。 – user776686
您的Plunker确实错过了“do”操作符的导入。另见http://*.com/questions/34515173/angular-2-http-get-with-typescript-error-http-get-map-is-not-a-function-in/34515276#34515276 –