在angular 2中将自定义表单控件连接到它的父表单验证



我最近尝试用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是未定义的,并且在自定义控件表单中对它进行了必要的验证,它也将为真。

我不知道你的自定义控件的行为,但下面的解决方案是有效的,即使你是动态编译组件本身。

即使在模板驱动表单的场景中(如您的场景),底层引擎仍然通过利用响应性组件(FormGroupFormControl)来工作。因此,您始终可以通过编程方式更改组和子控件的层次结构,以按预期传播更改。例如,您可以为接受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

相关内容

  • 没有找到相关文章

最新更新