Динамический шаблон в компоненте Angular 6 - PullRequest
0 голосов
/ 05 октября 2018

Я новичок в Angular, поэтому мне жаль, если я облажался с жаргоном.Я пытаюсь динамически использовать templateURL (html) в моем компоненте, функция Class останется прежней, но html изменится в зависимости от binType

Это мой источник класса компонента

import { Component, OnInit, Input, Output, EventEmitter, AfterViewInit, ViewContainerRef, ViewChild, Compiler, Injector, NgModule, NgModuleRef } from '@angular/core';

declare var module: {
  id: string;
}

@Component({
  selector: 'app-cart-bin',
  styleUrls: ['./cart-bin.component.css'],  
  template: ` 
      <ng-template #dynamicTemplate></ng-template>
    `

})

export class CartBinComponent implements AfterViewInit, OnInit {

  @ViewChild('dynamicTemplate', {read: ViewContainerRef}) dynamicTemplate;


  public cols = 3;
  public rows = 3;

  @Input() binType = "";

  @Input() toteList = [];

  @Output() callbackMethod = new EventEmitter<string>();

  constructor(private _compiler: Compiler, private _injector: Injector, private _m: NgModuleRef<any>) { }

  ngOnInit() {
    console.log(this.binType);
  }

  ngAfterViewInit() {

    let tmpObj;

    console.log(tmpObj);

    if ((this.binType) == "2") {
      tmpObj = {
        moduleId: module.id,
        templateUrl : './cart-bin.component_02.html'
      };
    } else {
      tmpObj = {
        moduleId: module.id,
        templateUrl : './cart-bin.component_01.html'
      };
    }

    console.log(tmpObj);

    const tmpCmp = Component(tmpObj)(class {});

    const tmpModule = NgModule({declarations: [tmpCmp]})(class {});

    this._compiler.compileModuleAndAllComponentsAsync(tmpModule).then((factories) => {
      const f = factories.componentFactories[0];
      const cmpRef = f.create(this._injector, [], null, this._m);
      cmpRef.instance.name = 'dynamic';
      this.dynamicTemplate.insert(cmpRef.hostView);
    });
}

  getToteBoxClass(toteData){
    ...
  } 

  getToteIcon(toteData){
    ...
  }

  toteSaveClick(toteData){
    ...
  }
}

Это компилируется, но шаблон не разбирается и появляется следующая ошибка

ERROR Error: Template parse errors:
Can't bind to 'ngStyle' since it isn't a known property of 'div'.

HTML верен, я использовал его непосредственно как часть @Component TypeDecorator

1 Ответ

0 голосов
/ 05 октября 2018

Помимо того факта, что использование компилятора и создание динамических компонентов является довольно анти-паттерном в угловом формате, я полагаю, что вы можете исправить свою ошибку, добавив CommonModule в объявление NgModule:

NgModule({imports: [CommonModule], declarations: [tmpCmp]})

Лучше быТем не менее, чтобы использовать ngSwitchCase в своем шаблоне, создайте два компонента, которые наследуются от базового компонента, но имеют разные шаблоны, и в зависимости от binType позволяют ему отображать один или другой компонент:

template:

<ng-container [ngSwitch]="binType">
  <cart-bin-1 *ngSwitchCase="1"></cart-bin-1>
  <cart-bin-2 *ngSwitchCase="2"></cart-bin-2>
</ng-container>

ts:

export abstract class CartBin {
  // some common cart bin logic here:
}


@Component({
  selector: 'cart-bin-1',
  templateUrl: './cart-bin.component_01.html' 
})
export class CartBin1 extends CartBin {

}

@Component({
  selector: 'cart-bin-2',
  templateUrl: './cart-bin.component_02.html' 
})
export class CartBin2 extends CartBin  {

}

Преимущество использования этого заключается в том, что в комплект AOT больше не будет включен компилятор, и поэтому приложение будет меньше.и быстрее.Кроме того, это выглядит намного лучше:)

...