Angular 2 RC1:DataBinding和ComponentResolver

时间:2016-05-25 14:09:40

标签: javascript typescript angular

我最近将我的项目从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()

0 个答案:

没有答案