自定义 angular2 表单输入组件,在组件内具有两种方式绑定和验证 [英] Custom angular2 form input component with two way binding and validation inside a component
问题描述
有没有办法制作一个双向绑定输入组件,它也可以在组件内部进行验证?
我想要实现的是拥有一个可以在表单中排列的组件,如下所示:
我有以下设置,但不知道如何正确设置:
组件:
从 'angular2/core' 导入 {Component,Input, Output,EventEmitter}从'angular2/common'导入{FORM_DIRECTIVES};@成分({选择器:'我的表单输入',指令:[FORM_DIRECIVES],模板:`<input type="text" class="form-control" id="i1" required [ngModel]="inputModel" (ngModelChange)="onChangeInput($event)" ngControl="ctrl" #ctrl="ngForm"/><p>{{"字段有效吗?我想在这里做出一些决定:"+ctrl.valid}}</p>`})导出类 InputComponent {构造函数(){};@Input() inputField:string;@Input() inputModel: 对象;@Output() inputModelChange = new EventEmitter();onChangeInput(事件){this.inputModel=事件;this.inputModelChange.emit(事件);}}
应用:
//我们的根应用组件从 'angular2/core' 导入 {Component}从'angular2/common'导入{FORM_DIRECTIVES};从 './my.input' 导入 {InputComponent}@成分({选择器:'我的应用',提供者:[],模板:`<div><p>有没有办法使自定义的 2 路绑定表单输入组件也具有验证功能?</p><form #f="ngForm"><my-form-input [(inputModel)]="name" [inputField]="myFormInputName"></my-form-input><p>{{name}}</p></表单>
`,指令:[InputComponent,FORM_DIRECIVES]})出口类应用{构造函数(){this.name = 'Angular2'}}
我还做了一个 Plunker 来说明我的问题:http://plnkr.co/edit/0vXjHbQmv7v7EKQcLWaa?p=预览
您可以将表单控件传递给您的组件来为输入创建专用控件.基于这个新控件,当它们的 valid
属性为 false
时显示错误:
@Component({选择器:'我的表单输入',指令:[FORM_DIRECIVES],模板:`<input type="text" class="form-control" id="i1"[ngModel]="输入模型"(ngModelChange)="onChangeInput($event)"[ngFormControl]="formCtrl.controls[inputField]"/><p>字段是否有效?我想做一些决定这里取决于:{{formCtrl.controls[inputField].valid}}</p>`})导出类 InputComponent 实现 OnInit {@Input() inputField:string;@Input() formCtrl;@Input() inputModel: 对象;@Output() inputModelChange = new EventEmitter();ngOnInit() {this.formCtrl.control.addControl(this.inputField, new Control('', Validators.required));}onChangeInput(事件){this.inputModel=事件;this.inputModelChange.emit(事件);}}
您需要使用 addControl
方法使整个表单的状态与您在输入组件中创建的控件保持一致.
在您的情况下,您使用 ngControl
指令内联定义控件.我做了一些测试,但我不能让它以这种方式工作...
这里是从父组件使用这个组件的方法:
@Component({选择器:'我的应用',模板:`<form #f="ngForm"><my-form-input [(inputModel)]="name" [inputField]="myFormInputName" [formCtrl]="f"></my-form-input></表单>`,指令:[FORM_DIRECTIVES, InputComponent]})导出类 AppComponent {}
刚启动后仍然是一个检查问题.表单的全局状态未更新,出现以下错误:
表达式 '有效 : AppComponent@1:24' 中的 {{f.valid}} 在检查后已更改.以前的值:'有效:真'.当前值: '有效:假'
要解决这个问题,请查看基于 ChangeDetectorRef
类及其 detectChanges
方法的 Julien 的答案...
这是一个示例 plunkr:https://plnkr.co/edit/Z4uOUq2q4iXdpo0J6R1o?p=预览.
Is there a way to make a two way binding input component, that can also have a validation inside the component?
What I'm trying to achieve is to have a components that I could line up in my forms as follows:
<form #f="ngForm">
<my-form-input [(inputModel)]="name" [inputField]="myFormInputName"></my-form-input>
<my-form-input [(inputModel)]="name2" [inputField]="myFormInputName2"></my-form-input>
...
<my-form-input [(inputModel)]="lastItem" [inputField]="lastItemName"></my-form-input>
</form>
I have a following setup and can't figure out, how to make it right:
The component:
import {Component,Input, Output,EventEmitter} from 'angular2/core'
import {FORM_DIRECTIVES} from 'angular2/common';
@Component({
selector: 'my-form-input',
directives: [FORM_DIRECTIVES],
template:
`
<input type="text" class="form-control" id="i1" required [ngModel]="inputModel" (ngModelChange)="onChangeInput($event)" ngControl="ctrl" #ctrl="ngForm"/>
<p>{{"Is field valid? I would like to make some decisions here depending on that: "+ctrl.valid}}</p>
`
})
export class InputComponent {
constructor(){};
@Input() inputField:string;
@Input() inputModel: Object;
@Output() inputModelChange = new EventEmitter();
onChangeInput(event){
this.inputModel=event;
this.inputModelChange.emit(event);
}
}
The app:
//our root app component
import {Component} from 'angular2/core'
import {FORM_DIRECTIVES} from 'angular2/common';
import {InputComponent} from './my.input'
@Component({
selector: 'my-app',
providers: [],
template: `
<div>
<p>Is there a way to make a custom 2 way binding form input component having also validation?</p>
<form #f="ngForm">
<my-form-input [(inputModel)]="name" [inputField]="myFormInputName"></my-form-input>
<p>{{name}}</p>
</form>
</div>
`,
directives: [InputComponent,FORM_DIRECTIVES]
})
export class App {
constructor() {
this.name = 'Angular2'
}
}
I also made a Plunker to ilustrate my problem: http://plnkr.co/edit/0vXjHbQmv7v7EKQcLWaa?p=preview
You can pass the form control to your component to create a dedicated control for the input. Based on this new control to display errors when their valid
attributes are false
:
@Component({
selector: 'my-form-input',
directives: [FORM_DIRECTIVES],
template: `
<input type="text" class="form-control" id="i1"
[ngModel]="inputModel"
(ngModelChange)="onChangeInput($event)"
[ngFormControl]="formCtrl.controls[inputField]"/>
<p>Is field valid? I would like to make some decisions
here depending on that: {{formCtrl.controls[inputField].valid}}
</p>
`
})
export class InputComponent implements OnInit {
@Input() inputField:string;
@Input() formCtrl;
@Input() inputModel: Object;
@Output() inputModelChange = new EventEmitter();
ngOnInit() {
this.formCtrl.control.addControl(
this.inputField, new Control('', Validators.required));
}
onChangeInput(event){
this.inputModel=event;
this.inputModelChange.emit(event);
}
}
You need to use the addControl
method to make the state of your whole form consistent with controls you created within your input components.
In your case, you define your controls inline using the ngControl
directive. I made some tests but I can't make it work this way...
Here is the way to use this component from the parent one:
@Component({
selector: 'my-app',
template: `
<form #f="ngForm">
<my-form-input [(inputModel)]="name" [inputField]="myFormInputName" [formCtrl]="f"></my-form-input>
</form>
`,
directives: [ FORM_DIRECTIVES, InputComponent ]
})
export class AppComponent {
}
It remained a check problem just after starting. The global state of the form wasn't updated and the following error occured:
Expression '
Valid : {{f.valid}} in AppComponent@1:24' has changed after it was checked. Previous value: '
Valid : true'. Current value: '
Valid : false'
To fix this aspect, have a look at the Julien's answer based on the ChangeDetectorRef
class and its detectChanges
method...
Here is a sample plunkr: https://plnkr.co/edit/Z4uOUq2q4iXdpo0J6R1o?p=preview.
这篇关于自定义 angular2 表单输入组件,在组件内具有两种方式绑定和验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!