Angular 动态组件:如何设置和获取数据

Angular Dynamic Components: How to Set and Get Data

我需要根据预先确定的类型动态创建组件,并能够设置和获取数据。 到目前为止,我能够创建和显示组件,但我不知道如何设置或从中获取数据。

这就是我添加和显示组件的方式:

app.component.ts:

export class AppComponent {

    components: any[] = [];

    constructor(private componentFactoryResolver: ComponentFactoryResolver) { }


    addField(type: string) {

        let component: any;

        switch (type) {

            case 'string':
                // how to set data in the created component??
                component = StringComponent;
                break;

            //...
        }

        const childComponent = this.componentFactoryResolver.resolveComponentFactory(component);
        this.components.push(childComponent);
    }

    getComponentData() {
        this.components.forEach(component => {
            // how to access the data from each component??
        });
    }
}

app.component.html:

<div class="col-12" cdkDropList (cdkDropListDropped)="drop($event)">
  <div cdkDrag *ngFor="let cmp of components">
    <div class="row">
      <div class="col-10">
        <app-string *ngIf="cmp.selector == 'app-string'"></app-string>
        <!-- (...) -->
      </div>
      <div class="col-2 field-btn pt-4">
        <button type="button" mdbBtn color="danger" mdbWavesEffect>
          <mdb-icon fas icon="times"></mdb-icon>
        </button>
        <button cdkDragHandle type="button" class="move" mdbBtn color="info" mdbWavesEffect>
          <mdb-icon fas icon="arrows-alt"></mdb-icon>
        </button>
      </div>
    </div>
  </div>
</div>

string.component.ts:

export class StringComponent implements OnInit {

  item = new Item();

  constructor() { }

  ngOnInit() {
  }
}

string.component.html:

<div class="form-row mb-3">
  <div class="form-group col-12 col-md-6">
    <label for="name">Field Name</label>
    <input mdbInput type="text" [(ngModel)]="item.value" class="form-control" id="name" placeholder="Field Name" (keyup)="onInputValueChange($event.target.value)">
  </div>

  <div class="form-group col-12 col-md-3">
    <label for="identifier">Identifier</label>
    <input mdbInput type="text" [(ngModel)]="item.id" class="form-control" id="identifier" placeholder="Autogenerated ID" disabled>
  </div>

  <div class="form-group col-12 col-md-3">
      <label for="type">Type</label>
      <input mdbInput type="text" class="form-control" id="type" placeholder="STRING" disabled>
    </div>
</div>

动态添加的组件列表结果:

我没有使用 ng-template 添加组件,因为我可以将它们拖放到父组件的 cdkDropList 容器中。

我想要实现的是在将组件添加到列表之前设置 属性 'item.type' 的值,并能够获取每个组件 'item' 属性 在我填写他们的输入后。

设置和获取组件信息的最佳方法是什么?

更新:感谢@kari 的解决方案,我设法解决了我的问题。 这是结果:

我举例说明了如何使用 @Input()@Output() 从动态组件传递和检索数据:https://stackblitz.com/edit/angular-z6wssp

我认为它按您想要的方式工作。

我基本上建议您将组件 数据都推送到您的组件数组:

    compAndData.component = childComponent;
    compAndData.data = data;
    this.components.push(compAndData);

然后将数据传递给组件中的 @Input() 变量,并通过 EventEmitterOutput():

检索更改
<app-string [data]="cmp.data" (changedData)="onCompDataChanged($event)" *ngIf="cmp.component.selector === 'app-string'"></app-string>

尝试示例:更改字段名称,单击 GetComponentData 按钮并在控制台中检查检索到的数据。