动态创建的组件添加在页面末尾而不是直接底部

Dynamically created component added at the end of the page instead of immediate bottom

stackblitz

我正在尝试实现分层组件视图,为此我创建了 3 级层次结构。当用户单击任何级别时,应打开其对应的子级别。

我已经使用 ComponentFactoryResolver 并创建了组件 运行 次,因为我希望每个子实例都不同。

一切正常,我唯一的问题是,新创建的组件正在页面底部添加。我希望新添加的组件应该添加到点击行的底部。查看下图中的问题。

随意编辑这个stackblitz

看起来新组件正在添加到模板的末尾,因为 tRef 始终未定义。这会导致始终调用以下块:

if (!this.tRef) {
     this.setTemplate.emit(this);
}

并且以下始终计算为 false:

if (this.tRef && this.row) 

我添加了已评论的模板参考,并且 hirechy 似乎按预期工作:

<mat-row *matRowDef="let row; columns: displayedColumns;" class="element-row" 
       [cdkDetailRow]="row"
       (toggleChange)="onToggleChange($event,row)" 
       (setTemplate)="setTemplate($event,row)"
       [cdkDetailRowTpl]="tpl">
</mat-row>

就更新行详细信息而言,这是因为 set currentPosition 正在被调用,因为它正在检测 level2Pos 字段中的更改。可能有更好的方法,但是您设置方法的快速解决方案是包装 set 方法逻辑,以便仅在第一次设置位置:

set currentPosition(val: number) {
    if(!this.l2Pos) {
      this.dataSource2.data = data2.filter(x => x.position === val);
      this.dataSource2.paginator = this.paginator2;
      this.dataSource2.sort = this.sort;
      this.l2Pos = val;
    }
}

或者,您可以通过将位置包装在一个对象中并始终传递相同的引用来利用 Angular 的变化检测。

创建包装器对象:

export interface PositionContext {
  position: number;
}

确保始终将相同的引用传递给模板:

(table-basic-example.ts)
levelTwoPositionContext: PositionContext = {position: null};

.

(table-basic-example.html)
<ng-template #tpl let-element let-row="row">
    <level2 [currentPosition]="levelTwoPositionContext"></level2>
</ng-template>

更新换行位置:

(table-basic-example.ts)
this.levelTwoPositionContext.position = row.position;

集合中不需要额外的逻辑:

@Input()
  set currentPosition(val: PositionContext) {
      this.dataSource2.data = data2.filter(x => x.position === val.position);
      this.dataSource2.paginator = this.paginator2;
      this.dataSource2.sort = this.sort;
  }