在孩子中访问父母的ngForm

rob*_*más 6 angular

我有这样的结构:

<form #myForm="ngForm">
  <div class=row>
    <app-section-a [myForm]="myForm"></app-section-a>
Run Code Online (Sandbox Code Playgroud)

和我的孩子组件:

@Component({
...
  viewProviders: [ { provide: ControlContainer, useExisting: NgForm } ]
})
// ...
@Input() myForm: ElementRef;
Run Code Online (Sandbox Code Playgroud)
<input ...>
<button type=submit [disabled]="!myForm.valid">
Run Code Online (Sandbox Code Playgroud)

而且,这可以完美地确保表格中的所有组成部分都被计入有效性。问题是,我认为我不需要直接将 ngForm 的引用作为输入传递。我如何跳过该输入并仍然使其正常工作?

一个细节:恰好是一个 Angular 5 项目。

Gau*_*rda 9

完整的工作示例在此StackBlitz Link中。

首先,您根本不需要传递ngForm给子组件。ControlContainer因为您可以使用并通过提供给子组件提供程序数组来判断子组件是父表单组的一部分NgForm

在此示例中,一个父组件app.component正在加载子组件*ngFor,我们刚刚添加ControlContainer到子组件的提供者数组中。在这里,我们只需要动态地为每个子组件指定不同的名称,为此,我们需要传递@Input()子组件的索引并将其分配给nameinputField 的属性。

如果任何一个 inputControl 出现错误,则submit父控件的按钮将被禁用。

app.component.html是...

<form #heroForm="ngForm" class="container">
   <div id="parent" *ngFor="let i of [0,1,2]"  >
      <app-child [id]="i+1" [name]="i+1" ></app-child>
   </div>
  <hr>
    {{heroForm.value | json}}
  <hr>
  <div>
     <app-button-submit></app-button-submit>
  </div>
</form>
Run Code Online (Sandbox Code Playgroud)

应用程序按钮提交.html

<button type="submit" class="btn btn-success"
  [disabled]="!control.form.valid">Submit</button>
Run Code Online (Sandbox Code Playgroud)

我们通过依赖注入直接绑定到按钮的状态。请参阅下面的类ControlContainer文件。[disabled]constructor()

应用程序按钮提交.ts

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

@Component({
   selector: 'app-button-submit',
   templateUrl: './button-submit.component.html',
   styleUrls: ['./button-submit.component.css'],
   providers : [{provide : ControlContainer, useExisting : NgForm}]
})
export class ButtonSubmitComponent  {
   constructor(private control : NgForm) { }
}
Run Code Online (Sandbox Code Playgroud)

子组件.html

<div class="form-group" >
   <label [for]="Name">Name</label>    
      <input type="text"  class="form-control"  [id]="id" required [(ngModel)]="vname" [name]="Name"  #names="ngModel">
        {{vname}}
   <div [hidden]="names.valid || names.pristine" class="alert alert-danger"> 
      Name is required  
   </div>
</div>
Run Code Online (Sandbox Code Playgroud)

子组件.ts

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

@Component({
   ---,
   viewProviders: [ { provide: ControlContainer, useExisting: NgForm } ]
})
 export class ChildComponent implements OnInit {
   @Input('id') id;
   @Input ('name') Name;
 }
Run Code Online (Sandbox Code Playgroud)

在这里,ControlContainer将负责NgForm父组件到子组件的绑定。