我一直在调整Angular 2中的被动表单和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)
);
订阅。我不明白为什么某些形式的订阅似乎不被允许。
do
This plunker重现问题(打开DevTools控制台以查看错误):
ZoneAwareError {stack:&#34;错误:未捕获(承诺):TypeError:不能se...g.com/zone.js@0.7.5/dist/zone.js:349:25)[]&# 34;,message:&#34; Uncaught(in promise):TypeError:无法设置prope ... ore.umd.js:8486:93)↵在Array.forEach(native)&#34 ;, originalStack:&#34;错误:未捕获(承诺):TypeError:无法执行... ps://unpkg.com/zone.js@0.7.5/dist/zone.js:349:25)&#34;,zoneAwareStack:&#34;错误:未捕获(承诺):TypeError:不能se...g.com/zone.js@0.7.5/dist/zone.js:349:25)[]&#34;,名称:&#34;错误&# 34; ...}
第一种模式(format()
)确实不是非法的吗?
答案 0 :(得分:2)
这让你的傻瓜工作:
import 'rxjs/add/operator/do';
.do(changes =&gt; { console.log('名称已更改:',更改) })
完成已更改的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")
}
答案 1 :(得分:2)
其中一种方式是:
debounceTime 将在给定的毫秒后进行订阅。如果不需要,请忽略。
distinctUntilChanged 只会强制订阅实际值。
this.form.controls['form_control_name']
.valueChanges
.debounceTime(MilliSeconds)
.distinctUntilChanged()
.subscribe(val => {
});
答案 2 :(得分:0)
我也遇到了这个问题。
我想在我的情况下做debounceTime,所以它没有解决我的需求。
我其实忘了订阅!
但我能够通过这种方式获得价值变化:
this.form.get('name').valueChanges.forEach(
(value) => {console.log(value);} )
来自Angular文档中的hero-detail-component.ts
答案 3 :(得分:0)
您可以订阅整个表单并选择要“接受”的内容,就像这样...此外,不要忘记跟踪订阅并使用生命周期钩子取消订阅。此外,请等到视图已加载以订阅更改。这种模式效果很好。
private DEBOUNCE_TIME_FORM_INPUT = 250
private ngUnsubscribe: Subscription = new Subscription();
constructor(private fb: FormBuilder) {}
ngOnInit(): void {
this.initForm();
}
ngAfterViewInit(): void {
this.subscribeToFilters();
}
ngOnDestroy(): void { // Don't forget to close possible memory leak
this.ngUnsubscribe.unsubscribe();
}
private initForm(): void {
this.form = this.fb.group({
name: ['', []],
});
}
private subscribeToFilters(): void {
this.ngUnsubscribe.add(
this.form.valueChanges
.pipe(debounceTime(this.DEBOUNCE_TIME_FORM_INPUT)) // Debounce time optional
.subscribe((form): void => {
const { name } = form
console.log('Name', name);
}))
)
}
get name(): AbstractControl { return this.form.get(['name']); }