这只是疯狂,看起来没有办法让一个表单中的一个输入在子组件中.
我已阅读所有博客和教程以及所有内容,无法解决这个问题.
问题是当一个子组件要有任何形式的指令(ngModel,ngModelGroup或其他......)时,它不会工作.
这只是模板驱动表单中的一个问题
这是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; 
  }
}
Run Code Online (Sandbox Code Playgroud)
    yur*_*zui 56
一个简单的解决方案是提供ControlContainer在viewProviders像你的孩子组成的数组:
import { ControlContainer, NgForm } from '@angular/forms';
@Component({
 ...,
 viewProviders: [ { provide: ControlContainer, useExisting: NgForm } ]
})
export class ChildComponent {}
Run Code Online (Sandbox Code Playgroud)
另请阅读本文,解释其工作原理.
更新
如果您正在寻找嵌套模型驱动的表单,那么这里是类似的方法:
@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))
  }
}
Run Code Online (Sandbox Code Playgroud)
如果你ControlContainer不确切知道自定义组件的包装类型(例如你的控件在FormArray指令中),那么只需使用通用版本:
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 {}
Run Code Online (Sandbox Code Playgroud)
        Joh*_*lph 22
通过阅读一堆相关的github问题[1]  [2],我还没有找到一种直接的方法来将一个孩子Component的控件添加到父级ngForm(有些人也称它们为嵌套形式,嵌套输入或复杂控件) .
所以我将在这里展示的是一种适用于我的解决方法,ngForm为父母和孩子使用单独的指令.它并不完美,但它让我足够接近我停在那里.
我childFormComponent用一个ngForm指令声明我(即它不是一个html表单标签,只有指令):
<fieldset ngForm="addressFieldsForm" #addressFieldsForm="ngForm">
  <div class="form-group">
    <label for="email">Email</label>
    <input type="email" class="form-control" [(ngModel)]="model.email" name="email" #email="ngModel" required placeholder="Email">
  </div>
  ...
Run Code Online (Sandbox Code Playgroud)
然后,Component公开addressFieldsForm作为属性,并将自身导出为模板引用变量:
@Component({
  selector: 'mst-address-fields',
  templateUrl: './address-fields.component.html',
  styleUrls: ['./address-fields.component.scss'],
  exportAs: 'mstAddressFields'
})
export class AddressFieldsComponent implements OnInit {
  @ViewChild('addressFieldsForm') public form: NgForm;
  ....
Run Code Online (Sandbox Code Playgroud)
然后,父表单可以使用子表单组件,如下所示:
  <form (ngSubmit)="saveAddress()" #ngFormAddress="ngForm" action="#">
    <fieldset>
      <mst-address-fields [model]="model" #addressFields="mstAddressFields"></mst-address-fields>
      <div class="form-group form-buttons">
        <button class="btn btn-primary" type="submit" [disabled]="!ngFormAddress.valid || !addressFields.form.valid">Save</button>
      </div>
    </fieldset>
  </form>
Run Code Online (Sandbox Code Playgroud)
请注意,提交按钮显式检查表单ngFormAddress和addressFields表单上的有效状态.这样我至少可以合理地组成复杂的形式,即使它有一些样板.
另一种可行的解决方法
@Directive({
    selector: '[provide-parent-form]',
    providers: [
        {
            provide: ControlContainer,
            useFactory: function (form: NgForm) {
                return form;
            },
            deps: [NgForm]
        }
    ]
})
export class ProvideParentForm {}
Run Code Online (Sandbox Code Playgroud)
只需将此指令放在节点层次结构顶部的某个子组件中(在任何ngModel之前).
工作原理:NgModel 使用@Host()限定父表单的依赖项查找.因此,父组件中的表单对子组件中的NgModel不可见.但我们可以使用上面演示的代码注入并在子组件中提供它.
|   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           14892 次  |  
        
|   最近记录:  |