我需要根据预定的类型动态创建组件,并能够设置它们并从中获取数据。到目前为止,我仍然可以创建和显示组件,但是我不知道如何设置组件或从中获取数据。
这是我添加和显示组件的方式:
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()
变量,并通过EventEmitter
和Output()
检索更改:
<app-string [data]="cmp.data" (changedData)="onCompDataChanged($event)" *ngIf="cmp.component.selector === 'app-string'"></app-string>
尝试示例:更改字段名称,单击GetComponentData按钮并在控制台中检查检索到的数据。