Angular 2 : Component to render table with static <td>s and dynamic <td>s from another component

标签 angular angular2-template angular2-directives angular2-components

我有一个 Angular 2 组件,它可以呈现一个带有小猫对象数据的漂亮表格。

由于一些列将在不同的组件中重复使用,我正在寻找一种方法来提取 <td>到一个单独的组件( dynamic-kitten-tds )。我不能动<td>渲染 kitten.namekitten.lastWashed因为它们是 cat-o-base 所独有的组件:

cat-o-base.component.html

<table>
<tbody>
    <tr *ngFor="let kitten of kittenBasket">
        <td>{{ kitten.name }}</td>

        <dynamic-kitten-tds [value]="kitten"></dynamic-kitten-tds>

        <td>{{ kitten.lastWashed | date }}</td>
    </tr>
</tbody>
<table>

动态小猫-tds.component.html

dynamic-kitten-tds的整个模板组件看起来像这样:

<td *ngFor="let preference of kitten.preferences">{{ preference | json }}</td>

限制 1

我可能使用 *ngFor像这样:

<td>{{ kitten.name }}</td>
<td *ngFor="let preference of kitten.preferences" [value]="preference"></td>
<td>{{ kitten.lastWashed | date }}</td>

此限制来自必须作为 dynamic-kitten-tds 的一部分实现的业务逻辑。组件。

限制 2

代码必须产生有效的 DOM 发射。

问题

我该如何实现它?使用辅助组件就可以了。使用特殊的结构指令也很好。

附注

我查看了其他一些 SO 问题(例如 this one ),但没有找到完全匹配的问题定义。

最佳答案

如果使用辅助组件可以的话,我的想法是:

动态导出.ts

@Directive({selector: '[dynamicOutlet]'})
export class DynamicOutlet implements OnChanges, OnDestroy {
  @Input() dynamicOutlet: Type<any>;
  @Input() dynamicOutletModel: any;

  private componentRef: ComponentRef<any> = null;

  constructor(private vcRef: ViewContainerRef) {}

  ngOnChanges(changes: SimpleChanges) {
    this.vcRef.clear();
    this.componentRef = null;

    if (this.dynamicOutlet) {
      const elInjector = this.vcRef.parentInjector;
      const componentFactoryResolver = elInjector.get(ComponentFactoryResolver);

      const componentFactory = componentFactoryResolver.resolveComponentFactory(this.dynamicOutlet);
      this.componentRef = componentFactory.create(elInjector);

      this.componentRef.changeDetectorRef.detectChanges();
      this.componentRef.instance.model = this.dynamicOutletModel;
      this.vcRef.createEmbeddedView(this.componentRef.instance.template, { $implicit: this.dynamicOutletModel });
    }
  }

  ngOnDestroy() {
    if(this.componentRef) {
      this.vcRef.clear();
      this.vcRef = null;
    }
  }
}

kitten.ts

@Component({
    selector: 'kitten-component',
    template: `
      <ng-template let-model>
        <td *ngFor="let preference of model.preferences">{{ preference | json }}</td>
      </ng-template>
    `
})
export class Kitten {
  @ViewChild(TemplateRef) template: TemplateRef<any>;

  model: any;
}

然后你就可以像这样使用它

查看

<ng-container *dynamicOutlet="kittenComp; model: kitten"></ng-container>

组件

kittenComp = Kitten;

不要忘记将 Kitten 组件添加到 entryComponents 数组中。

这里是Plunker Example

关于 Angular 2 : Component to render table with static <td>s and dynamic <td>s from another component,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43355148/

相关文章:

javascript - angular 2 - ngFor 动态函数

angular - 为什么 angular 找不到 app.js 文件并抛出 404 错误?

javascript - 如何按顺序调用两个 API 并将两者的数据作为单个 Observable 返回

typescript - 类型 'IArguments' 不是数组类型

Angular 2。异常 : No Directive annotation found on Alert

typescript - angular 2自定义指令OnInit

javascript - Angular2 单 ngFor 用于多个数组

javascript - Angular2中组件属性变化的Observable

angular - 绑定(bind) : Appending to href

angular - 如何在 Angular 2 的 ngFor 中设置绑定(bind)?