角动态组件加载指令变量undefined

时间:2018-03-06 20:34:26

标签: javascript angular typescript

我正在尝试增强我创建的角度表组件,以输出格式化的单元格内容而不仅仅是文本。我认为一组格式组件将是要走的路,因为它们必须包含html标签(通过简单地绑定到属性就可以剥离)。我猜管道可能是一个选项,但由于大部分功能都在基本组件中,因此我不希望在表格实例中使用特定代码。

所以我尝试了关于动态组件加载的Angular文档,并创建了一个[format-h​​ost]指令,将其全部链接到doc&试图调试。失败在使用该指令的组件中。

let viewContainerRef = this.formatHost.viewContainerRef; 

由于formatHost未定义,因此失败。该指令在模块中定义。

我正在使用VS2017角度SPA模板,角度为4.2.5 使用组件中的相关代码(保持简短):

export class PagedTableComponent implements OnInit, AfterViewInit{

@Input() pagedTable: PagedTable<any[]>;
@Output() tableState: EventEmitter<TableState> = new EventEmitter<TableState>();
…
@ViewChild(FormatDirective) formatHost: FormatDirective;
…
formatters: Formatter[] = [];

constructor(private componentFactoryResolver: ComponentFactoryResolver) {
}

loadFormatComponent() {
    let componentFactory = this.componentFactoryResolver.resolveComponentFactory(this.formatters[0].component);

    let viewContainerRef = this.formatHost.viewContainerRef;
    viewContainerRef.clear(); //??
    let componentRef = viewContainerRef.createComponent(componentFactory);
}

ngOnInit() {
  …
    //this.formatters.push(new Formatter(ContactFormatComponent, "test"));
    // this.loadFormatComponent();
}

ngAfterViewInit() {
    this.formatters.push(new Formatter(ContactFormatComponent, "test"));
    this.loadFormatComponent();
}

对于指令未定义的原因,我们将不胜感激。

指令:

import { Directive, ViewContainerRef } from '@angular/core';
@Directive({
    selector: '[format-host]',
    })

export class FormatDirective {
    constructor(public viewContainerRef: ViewContainerRef) { }
}

模板:

<td *ngFor="let column of pagedTable.tableConfig.columns"
     [ngClass]="{ 'cell-right' : column.justification ===  ColumnJustification.right, 'cell-center' : column.justification === ColumnJustification.center}">
....
<ng-template format-host></ng-template>
</td>

1 个答案:

答案 0 :(得分:0)

最后得到了一些工作 - (如果它可以帮助任何人,粘贴在下面)感谢ViewChildren的产品。我现在可以获得一个测试格式组件以显示内容 - 但仅当我在Chrome中逐步调试时。仅在浏览器中,列为空。我正在考虑计时问题(尝试过setTimeout),但无法理解Angular的复杂性。

模板现在看起来像:

<tr *ngFor="let row of pagedTable.pagedList?.tableData">
    <td *ngFor="let column of pagedTable.tableConfig.columns">
        <div *ngIf="column.format != undefined; else normalCell">                            
            <ng-template avFormatHost rowId="{{row.id}}" formatName="{{column.format}}"></ng-template>
        </div>
        <ng-template #normalCell>{{getCellContent(row, column)}}</ng-template>
    </td>
</tr>

及相关组件代码:

 @ViewChildren(FormatHostDirective) formatHostDirectives: QueryList<FormatHostDirective>;

...

loadFormatComponent() {
    setTimeout(() => {
        this.formatHostDirectives.forEach((formatHostDirective) => {

            let rowId = formatHostDirective.rowId;
            let row = { email: 'test email', telephone: '999999' };

            let componentType: any = FormatComponents[formatHostDirective.formatName];
            if (componentType) {
                let componentFactory = this.componentFactoryResolver.resolveComponentFactory(componentType);

                //formatHostDirective.viewContainerRef.clear(); //??
                let componentRef = formatHostDirective.viewContainerRef.createComponent(componentFactory);
                this.components.push(componentRef);
                (<FormatComponent>componentRef.instance).data = row;
            }

        });
    });


}

超时的使用是否正确?还是应该在其他地方?或完全不同的东西。你如何决定安全延误是什么?