在 Angular 中创建复合组件

Kis*_*ash 3 angular

我想创建一个Angular通用复合组件,它由一堆输入字段组成,可以在跨应用程序的多个组件中使用。

例如:考虑一个具有以下字段的 USER DETAIL 组件,

  • 电子邮件 - InputText 字段
  • 性别单选按钮。
  • 年龄组 - 下拉菜单
  • 描述 - 文本区域。

我想将此USER DETAIL组件包含在多个组件中,如下所示:

在此处输入图片说明

从传统智慧我可以说,我只是包含<app-userdetails>在多个组件中。

但是我如何处理提交的FormGroupData?我的意思是如何从UserDetail包含在另一个组件中的数据获取数据CreateEmployee

我不确定我是否正确解释了上述情况,请向我指出有关此的任何网络示例或现有问题。

Yer*_*kon 6

因此,对于您的子组件,您可以向他传递form添加/删除控件。

父组件模板

<form (ngSubmit)="onSubmit(form)" #form="ngForm">
        <a-comp [prop1]="name" [form]=form></a-comp>

      <button type="submit">Submit</button>
 </form>
Run Code Online (Sandbox Code Playgroud)

一些子组件:

// a comp
@Component({
  selector: 'a-comp',
  template: `
    <input [(ngModel)]="prop1"  name="name2" #myControl="ngModel"/>
    `

})
export class AComponent {
  @Input() form: NgForm;
  @Input() prop1 = 'Angular 5';

  @ViewChild('myControl') myControl: NgModel;

  ngOnInit() {
    //console.log(this.form, this.myControl);
    this.form.addControl(this.myControl);


  }
}
Run Code Online (Sandbox Code Playgroud)

代码示例

传递@Input给孩子的是没有必要的。但是子组件需要了解form.

2. 最简单的方法。通过使用权力DI

子组件。在您的情况下 UserDetails:

@Component({
  selector: 'a-comp',
  viewProviders: [{ provide: ControlContainer, useExisting: NgForm }],
  template: `
      <input [(ngModel)]="prop1"  name="prop1"/>
      <input [(ngModel)]="prop2"  name="prop2"/>
    `

})
export class AComponent {
  prop1 = 'Hello';
  prop2 = 'World';

  ngOnInit() { }
}
Run Code Online (Sandbox Code Playgroud)

正如你在@Component装饰器中看到的,我们设置了viewProviders. 所以当要求ControlContainer我们说 to useExisting: NgForm. 通过 AngularDI系统,它将向上查找第一个 parent NgForm

ViewProviders = 定义对其视图 DOM 子项可见的可注入对象集。

...

您可能会问:通过DI机制它应该搜索 provider 直到 root,但为什么它不会在组织结构中上升并找到 parent NgForm

ConstuctorngModel

 constructor(@Optional() @Host() parent: ControlContainer,
              @Optional() @Self() @Inject(NG_VALIDATORS) validators: Array<Validator|ValidatorFn>,
              @Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) asyncValidators: Array<AsyncValidator|AsyncValidatorFn>,
              @Optional() @Self() @Inject(NG_VALUE_ACCESSOR)
              valueAccessors: ControlValueAccessor[]) {
...
Run Code Online (Sandbox Code Playgroud)

注意@Optional() @Host() parent: ControlContainer. 它是@Optional 和@Host()。

@Host - 指定注入器应该从任何注入器检索依赖项,直到到达当前组件的宿主元素。

因此,这里的@Host()装饰器限制ngModel只搜索分配到的host组件ngModel

NgModel 构造函数

通过这种方法,无需@Input在子组件中创建绑定来获取父组件NgForm并手动添加 NgModels 控件。

StackBlitz 示例