我最近将我的项目从beta.15更新为RC1。现在,DynamicComponentLoader
已弃用。所以我使用ComponentResolver
重新编写了我的代码。
我的组件正确加载到另一个组件中,但我遇到了一个问题:数据绑定似乎不起作用。
这是我的代码:
@Component({
selector: 'browser-pane',
styleUrls: ['src/modules/component@browser/src/styles/pane.css'],
template: `
<li class="pane">
<ul class="nodes">
<li *ngFor="let node of nodes; let i = index" id="node-{{i}}"></li>
</ul>
</li>
`
})
export class PaneComponent implements OnInit {
@Input() nodeId: number;
@Input() nodes: any[];
@Input() fillerComponent: any;
@Input() mapComponentData: any;
constructor(private _injector: Injector, private _cr: ComponentResolver) {}
ngOnInit(): any {
this.nodes.forEach((node: any, i: number) => {
this._cr.resolveComponent(this.fillerComponent)
.then((factory: ComponentFactory) => factory.create(this._injector, null, `#node-${i}`))
.then((ref: ComponentRef<any>) => this.mapComponentData(ref.instance, node));
})
}
}
mapComponentData
只是将数据映射到组件ref的函数。在我的例子中,我动态创建的组件需要@Input()
名为'media'。此函数将执行以下指令:myComponentInstance.media = media;
。
这是填充组件(简化):
@Component({
selector: 'cmp-media-box',
styleUrls: ['src/modules/component@media-node/src/style.css'],
pipes: [ MediaCountPipe ],
template: `
<div class="media-node"
(click)="onClick()"
(dragover)="onDragover($event)"
(drop)="onDrop($event)"
[class.dropDisable]="!drop">
<span class="title">{{ media.title }}</span>
<div class="box" [class.empty]="isEmpty()">{{ media | mediaCount:'playlists':'channels' }}</div>
</div>
`
})
export class MediaNodeComponent {
@Input() media: Media;
private _OSelection:Observable<Media[]>;
private _selectionSubscription: Subscription;
private _removeAllFromSelection;
drop: boolean = false;
constructor(private _store:Store<AppStore>, private _mediaService:MediaService) {
setTimeout(() => this.initialize(), 0);
}
initialize():any {
if(this.media.type === MEDIA) {
this._OSelection = this._store.select(s => s['data@media'].selected);
this._removeAllFromSelection = mediaRemoveAll;
} else if(this.media.type === CHANNEL) {
this._OSelection = this._store.select(s => s['data@channel'].selected);
this._removeAllFromSelection = channelRemoveAll;
}
this.subscribeToSelection();
}
// ...
}
那么问题是什么?在此fillerComponent
中,定义了this.media
。如果我在console.log(this.media)
内加initialize
,我就能看到它。但我无法在模板中使用它。我尝试了很多东西:
{{media?.title}}
{{media.title | async}}
@Input()
media
并使用硬编码变量(以防万一)DynamicComponentLoader
:同样的结果。但我认为dcl后面使用ComponentResolver
(不确定,我正在检查这一点)换句话说:我不能在模板中使用变量。
我做错了什么?
谈到这段代码,还有一件我不明白的事情。我无法在填充组件上使用OnInit
:永远不会触发ngOnInit()
。这就是为什么我使用这个可怕的setTimeout()
。