2

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

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

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 的解决方案,我设法解决了我的问题。结果如下:

最终结果的动画 gif

4

1 回答 1

3

我举了一个例子,你可以如何使用和从动态组件中传递和检索数据@Input()@Output()https: //stackblitz.com/edit/angular-z6wssp

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

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

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

然后将数据传递给组件中的变量并通过and@Input()检索更改:EventEmitterOutput()

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

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

于 2019-12-09T22:23:20.500 回答