我最近尝试用angular 2创建我自己的自定义表单控件。自定义控件应该有2个输入,并编辑具有已知结构的现有对象。例如:
class model {
public fieldOne: number;
public fieldSec: number;
}
我遵循了我在这里找到的好的解释:编写自定义表单控件指南
它工作得很好,除了指南没有提到我如何连接自定义控件表单验证到使用它的表单。让我们看一个简化的例子:
自定义控件模板看起来像这样:
<form>
<input [(ngModel)]="existingModel.fieldOne">
<input [(ngModel)]="existingModel.fieldSec" required>
</form>
我们用它来编辑一个值为:
的现有模型{
fieldOne: 20,
fieldSec: undefined
}
在我的应用程序中我们需要自定义控件来编辑这个模型
<form #formVar="ngForm">
<my-custom-control [(ngModel)]="existingModel" required>
</my-custom-control>
</form>
这种例子在我的应用程序中工作,我可以编辑模型。问题是,我想显示用户时,表单是无效的,如果我看formVar。即使existingModel.fieldSec
是未定义的,并且在自定义控件表单中对它进行了必要的验证,它也将为真。
我不知道你的自定义控件的行为,但下面的解决方案是有效的,即使你是动态编译组件本身。
即使在模板驱动表单的场景中(如您的场景),底层引擎仍然通过利用响应性组件(FormGroup
和FormControl
)来工作。因此,您始终可以通过编程方式更改组和子控件的层次结构,以按预期传播更改。例如,您可以为接受NgForm
:
@Input('form') peerForm : NgForm;
@Input('entity') model : any;
然后在视图中设置绑定:
<form #formVar="ngForm">
<my-custom-control [entity]="existingModel" [form]="formVar">
</my-custom-control></form>
你的组件模板应该看起来像:
<div>
<input [(ngModel)]="model.fieldOne" #ctrl1="ngModel">
<input [(ngModel)]="model.fieldSec" required #ctrl2="ngModel">
</div>
在你的组件代码中:
@ViewChild('ctrl1') ngModel1 : NgModel;
@ViewChild('ctrl2') ngModel2 : NgModel;
...
ngAfterViewInit(){
// assuming the form does exist (TODO: check if set here)
this.peerForm.control.addControl('entity_fieldOne', this.ngModel1.control);
this.peerForm.control.addControl('entity_fieldSec', this.ngModel2.control);
}
应该足够了。参见Plunker: https://plnkr.co/gb3XroZNoGuZa05e76X0