【问题标题】:Render dynamic template based on type基于类型渲染动态模板
【发布时间】:2019-10-28 00:28:38
【问题描述】:

我真的很喜欢为Dynamic template based on value rather than variable with ngTemplateOutlet 提供的答案。但是我无法让它工作。简化示例:

export class A {
}

export class MyComponent 
  implements OnInit {

  public controls$ = Observable<any[]>([]);

  ngOnInit() {
    this.controls$.next([new A()]);
  }

  public getTypeName(control: any) {
    if (control instanceof A) {
      return "AControl";
    }
    return "";
  }
}

模板:

<div *ngFor="let control of control$ | async">
  {{ getControlType(control) }}
</div>

产量:

控制

到目前为止一切顺利。添加模板时,出现异常:

<div *ngFor="let control of control$ | async">
  {{ getControlType(control) }}
  <ng-container 
    [ngTemplateOutlet]="getControlType(control)"
    [ngTemplateOutletContext]="{ control: control }">
  </ng-container>
</div>

<ng-template 
  #AControl 
  let-item="control">A Control</ng-template>

抛出:

templateRef.createEmbeddedView 不是函数

我不确定我需要更改什么才能使模板#AControl 在容器中呈现。

【问题讨论】:

    标签: angular typescript angular8


    【解决方案1】:

    似乎[ngTemplateOutlet]="getControlType(control)" 是罪魁祸首。我没有看到 getControlType() 的代码,但我想它返回的是一个 s 字符串,而它应该是一个 TemplateRef 对象。除非你使用ChangeDetectionStrategy.OnPush,否则在模板中调用函数不是一个好主意,所以我建议在你的模板中使用 switch 语句。然而,与

    @ViewChild("AControl", {static: true})
    AControl: TemplateRef<any>;
    

    您可以访问 .ts 文件中的模板并从 getControlType 函数返回

    【讨论】:

    • 如果控件是动态的并且可以重复,我将如何为每个项目动态创建一个TemplateRef? (可能有 10 个 AControl)
    【解决方案2】:

    D Pro's Answer 的帮助下,我发现,我真的不需要在我的实例中使用ngTemplateOutlet(对于我使用的简单的东西来说,它们似乎真的很复杂)。

    我的最终解决方案是:

    打字稿

    export class A {
    }
    
    export class B {
    }
    
    
    export class MyComponent 
      implements OnInit {
    
      public controlsTypes$ = Observable<any[]>([]);
    
      ngOnInit() {
        var value1 = new A();
        var value2 = new B();
        this.controls$.next([
          { control: value1, type: getTypeName(value1)},
          { control: value2, type: getTypeName(value2)},
        ]);
      }
    
      public getTypeName(control: any) {
        if (control instanceof A) {
          return "AControl";
        } else if (control instanceof B) {
          return "BControl";
        }
        return "";
      }
    
      public onClick(control: any) {
      }
    }
    

    html:

    <div *ngFor="let controlType of controlType$ | async"
         [ngSwitch]="controlType.type">
      <ng-template ngSwitchCase="AControl">
        <div (click)="onClick(controlType.control)">{{ controlType.type }}</div>
      </ng-template>
      <ng-template ngSwitchCase="BControl">
        <div (click)="onClick(controlType.control)">{{ controlType.type }}</div>
      </ng-template>
    </div>
    

    同时显示AControlBControl,当每个都被单击时,实例化的类被传递给onClick()

    【讨论】:

      猜你喜欢
      • 2020-10-28
      • 2011-11-07
      • 1970-01-01
      • 2020-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-06
      相关资源
      最近更新 更多