使用Angular 2,双向绑定在模板驱动的表单中很容易 - 您只需使用香蕉盒语法。您将如何以模型驱动的形式复制此行为?
例如,这是标准的反应形式。让我们假装它看起来比它看起来复杂得多,有很多种不同的输入和业务逻辑,因此比模板驱动的方法更适合模型驱动的方法。
export class ExampleModel {
public name: string;
// ... lots of other inputs
}
@Component({
template: `
<form [formGroup]="form">
<input type="text" formControlName="name">
... lots of other inputs
</form>
<h4>Example values: {{example | json}}</h4>
`
})
export class ExampleComponent {
public form: FormGroup;
public example: ExampleModel = new ExampleModel();
constructor(private _fb: FormBuilder) {
this.form = this._fb.group({
name: [ this.example.name, Validators.required ]
// lots of other inputs
});
}
this.form.valueChanges.subscribe({
form => {
console.info('form values', form);
}
});
}
在subscribe()
中,我可以将各种逻辑应用于表单值,并根据需要进行映射。但是,我不想映射表单中的每个输入值。我只想看到整个employee
模型的更新值,以类似于[(ngModel)]="example.name"
的方式,并显示在模板中的json管道中。我怎么能做到这一点?
注意:正如@Clouse24提到的那样,"Using Reactive Froms with ngModel is deprecated in angular 6 and will be removed in angular 7"(这意味着从第7版开始将不再支持下面的答案)。请阅读链接以查看弃用的原因并了解您将拥有的替代方案。
您可以将[(ngModel)]
与Reactive表单一起使用。
<form [formGroup]="form">
<input name="first" formControlName="first" [(ngModel)]="example.first"/>
<input name="last" formControlName="last" [(ngModel)]="example.last"/>
</form>
export class App {
form: FormGroup;
example = { first: '', last: '' };
constructor(builder: FormBuilder) {
this.form = builder.group({
first: '',
last: ''
})
}
}
这将是一个完全不同于没有formControlName
时使用的指令。对于反应形式,它将是FormControlNameDirective
。如果没有formControlName
,将使用NgModel
指令。
有时您可能需要将[(ngModel)]与Reactive表单相结合。我可能是一些你不需要作为表单一部分的输入控件,但你仍然需要将它绑定到控制器。然后你可以使用:[(ngModel)]="something" [ngModelOptions]="{standalone: true}"
以下是如何解决它:
为了得到two-way-binding
的结果
我使用本地“模板变量”并对两个字段使用相同的formControl。
<form [formGroup]="formGroup">
<input #myInput (input)="mySlider.value = myInput.value" type="number" formControlName="twoWayControl">
<mat-slider #mySlider (input)="myInput.value = mySlider.value" formControlName="twoWayControl" min="1" max="100">
</mat-slider>
</form>
当我以编程方式想要更改模型的值时,我使用setValue()
,就像其他人已经宣布的那样。
setTo33() {
this.formGroup.get('twoWayControl').setValue(33);
}
如果您只想显示输入值,只需在输入中创建一个变量并在模板中使用。
... lots of other inputs <h4>Example values: {{ name.value }}</h4>
// Allow two way binding on the [(name)] from the parent component
private nameValue: string;
@Input()
get name() {
return this.nameValue;
}
set name(values) {
this.nameValue = values;
this.nameChange.emit(this.nameValue);
}
@Output() nameChange = new EventEmitter<string>();
ngOnInit() {
// Update local value and notify parent on control value change
this.formControl.valueChanges.forEach(value => this.name = value));
}
ngOnChanges() {
// Update local value on parent change
this.formControl.setValue(this.expression);
}