Angular2嵌套模板驱动形式 [英] Angular2 nested template driven form

查看:77
本文介绍了Angular2嵌套模板驱动形式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这只是疯狂,看起来没有办法将其中之一的输入形式包含在子组件中.

This is just madness , looks like there is no way to have a form which one of it's inputs is in a child component .

我已经阅读了所有博客和教程以及所有内容,没有办法解决.

I have read all the blogs and tutorials and everything , no way to work this out .

问题是,当子组件将具有任何形式的格式指令(ngModel,ngModelGroup或其他任何..)时,它将无法正常工作.

The problem is when a child component is going to have any kind of form directives ( ngModel , ngModelGroup or whatever ..) , it wont work.

这只是模板驱动表单中的问题

This is only a problem in template driven forms

这是 plunker :

import { Component } from '@angular/core';

@Component({
  selector: 'child-form-component',
  template: ` 
  <fieldset ngModelGroup="address">
    <div>
      <label>Street:</label>
      <input type="text" name="street" ngModel>
    </div>
    <div>
      <label>Zip:</label>
      <input type="text" name="zip" ngModel>
    </div>
    <div>
      <label>City:</label>
      <input type="text" name="city" ngModel>
    </div>
  </fieldset>`
})

export class childFormComponent{


}

@Component({
  selector: 'form-component',
  directives:[childFormComponent],
  template: `
    <form #form="ngForm" (ngSubmit)="submit(form.value)">
      <fieldset ngModelGroup="name">
        <div>
          <label>Firstname:</label>
          <input type="text" name="firstname" ngModel>
        </div>
        <div>
          <label>Lastname:</label>
          <input type="text" name="lastname" ngModel>
        </div>
      </fieldset>

      <child-form-component></child-form-component>

      <button type="submit">Submit</button>
    </form>

    <pre>
      {{form.value | json}}
    </pre>

    <h4>Submitted</h4>
    <pre>    
      {{value | json }}
    </pre>
  `
})
export class FormComponent {

  value: any;

  submit(form) {
    this.value = form; 
  }
}

推荐答案

一个简单的解决方案是在子组件的viewProviders数组中提供ControlContainer,例如:

One simple solution is to provide ControlContainer in viewProviders array of your child component like:

import { ControlContainer, NgForm } from '@angular/forms';

@Component({
 ...,
 viewProviders: [ { provide: ControlContainer, useExisting: NgForm } ]
})
export class ChildComponent {}

Stackblitz示例

Stackblitz Example

还请阅读这篇文章,解释其工作原理.

Read also this article that explains why it's working.

更新

如果您要查找嵌套模型驱动的表单,那么这是类似的方法:

If you're looking for nested model driven form then here is the similar approach:

@Component({
  selector: 'my-form-child',
  template: `<input formControlName="age">`,
  viewProviders: [
    {
      provide: ControlContainer,
      useExisting: FormGroupDirective
    }
  ]
})
export class ChildComponent {
  constructor(private parent: FormGroupDirective) {}

  ngOnInit() {
    this.parent.form.addControl('age', new FormControl('', Validators.required))
  }
}

NG运行示例

Ng-run Example

如果您不确切知道哪种类型的ControlContainer包装您的自定义组件(例如,控件位于FormArray指令内),则只需使用通用版本:

If you don't know exactly which type of ControlContainer wraps your custom component(for example your controls is inside FormArray directive) then just use common version:

import { SkipSelf } from '@angular/core';
import { ControlContainer} from '@angular/forms';

@Component({
 ...,
 viewProviders: [{
   provide: ControlContainer,
   useFactory: (container: ControlContainer) => container,
   deps: [[new SkipSelf(), ControlContainer]],
 }]
})
export class ChildComponent {}

NG运行示例

Ng-run Example

这篇关于Angular2嵌套模板驱动形式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆