Angular 7可重用的ng模板

Angular 7可重用的ng模板,angular,angular2-template,ngx-datatable,ng-template,Angular,Angular2 Template,Ngx Datatable,Ng Template,我目前正在创建一个可重用的ngx datatable包装组件,它将在我的整个应用程序中使用,因为每个表都不同,我需要多个ng模板来满足每个组件的需求 我当时的想法是创建一个SharedTemplates组件,该组件将保存大量ng模板,并通过将它们作为公共属性公开,例如: @ViewChild(“yesNoTemplate”)公共yesNoTemplate:TemplateRef 以便我以后可以将它们用作: tableComponents:tableComponents=newtableCompo

我目前正在创建一个可重用的ngx datatable包装组件,它将在我的整个应用程序中使用,因为每个表都不同,我需要多个ng模板来满足每个组件的需求

我当时的想法是创建一个
SharedTemplates
组件,该组件将保存大量ng模板,并通过将它们作为公共属性公开,例如:

@ViewChild(“yesNoTemplate”)公共yesNoTemplate:TemplateRef

以便我以后可以将它们用作:

tableComponents:tableComponents=newtableComponents()

然而,这似乎不起作用,我假设tableComponents没有任何属性,因为它没有被渲染(?)

使用组件本身作为模板不起作用,因为我收到错误消息:

TypeError:templateRef.createEmbeddedView不是函数


如何存储这些模板以重复使用多次

该错误可能是使用不推荐的
模板造成的

因此,您应该使用
ng template
而不是
template


我不知道您使用的是哪个角度版本,但我遇到了类似的问题

在我的例子中,我使用Angular 9,我试图创建一个组件,其中必须加载一个模板,其中包含html,但也包含插值字符串“{}}”,并且还必须对其应用样式。因此,模板和样式都来自服务器

在我的探索过程中,我也试着问这个关于stackoverflow的问题:

在某个时候,我开始在Discord的编码社区中提问,有人给了我一个github的链接

感谢我收到的链接,我能够实现我所需要的:

“根据请求动态加载模板。”

这要归功于我们的努力

如果不是因为那个帖子,我现在的处境可能和你一样

我希望这是你需要的

哦,对于我使用的构建表(包括排序、过滤、分页等等),我不知道这对您的情况是否有意义

警告: 我必须提到,它有一个坏的影响。您不能在生产模式下构建项目,因为它不包含此解决方案所需的角度编译器。我试图自己解决这个问题,主要是因为应用程序的大小急剧增加(在我的例子中,从2mb增加到大约40-45mb)


您应该在根级别实例化
SharedTemplates
组件,然后将所有ng模板实例存储到共享服务中


下面是我在StackBlitz上的演示:

建议为所需的每个模板创建组件,然后使用“ComponentFactoryResolver”解析它们并附加到主机组件

提供了更大的扩展性

let type=YesNoComponent;
let factory=cfr.resolveComponentFactory(类型);

让instance=host.viewContainerRef.createComponent(工厂)您试图做的是以编程方式创建组件,然后访问它们的方法和属性

Angular创建组件实例的方式是使用将创建新组件的,以及将附着和渲染组件的

首先创建一个指令,该指令将作为一个表的ViewContainerRef,它将呈现组件(我认为您现在缺少的组件),并允许您访问其方法和属性

import { Directive, ViewContainerRef } from '@angular/core';

@Directive({
  selector: '[appTable]'
})
export class TableDirective {

  constructor(public viewContainerRef: ViewContainerRef) { }

}
现在,您可以将其添加到ng模板标记中,并使用FactoryResolver在其中呈现组件:


import { Component, ComponentFactoryResolver, ViewChild, OnInit, ComponentRef } from '@angular/core';
import { TableComponent } from './table/table.component';
import { TableDirective } from './table.directive';

@Component({
  selector: 'app-root',
  template: `
  <ng-template appTable></ng-template>
  `,
})
export class AppComponent implements OnInit {

  @ViewChild(TableDirective) tableHost: TableDirective;
  tableComponent: ComponentRef<TableComponent>;

  constructor(private componentFactoryResolver: ComponentFactoryResolver) {

  }

    ngOnInit() {

    // TableComponents = new TableComponents();  wrong way!

    /**
    * creating the component factory resolver
    */
    const tableFactory = this.componentFactoryResolver.resolveComponentFactory(TableComponent);
    const viewContainerRef = this.tableHost.viewContainerRef;

    /**
     * clearing just in case something else was rendered before
     */
    viewContainerRef.clear();

    /**
     * now you will be able to access the methods and properties of your component after this
     */
    this.tableComponent = viewContainerRef.createComponent(tableFactory);
  }
}

我做了一个更清楚的说明,你可以在Luka Onikadze的文章中阅读更多关于动态创建组件的内容。

你能提供你目前拥有的相关代码吗?这是使用
cellTemplate
模板创建表所需的最低要求(显然不是通过你想要采用的最终方法)。我使用的是ng模板,我面临的问题不是获取同一组件中的模板,而是从不同组件中获取模板。啊!我理解。您希望动态插入组件。也许这有助于:

import { Component, ComponentFactoryResolver, ViewChild, OnInit, ComponentRef } from '@angular/core';
import { TableComponent } from './table/table.component';
import { TableDirective } from './table.directive';

@Component({
  selector: 'app-root',
  template: `
  <ng-template appTable></ng-template>
  `,
})
export class AppComponent implements OnInit {

  @ViewChild(TableDirective) tableHost: TableDirective;
  tableComponent: ComponentRef<TableComponent>;

  constructor(private componentFactoryResolver: ComponentFactoryResolver) {

  }

    ngOnInit() {

    // TableComponents = new TableComponents();  wrong way!

    /**
    * creating the component factory resolver
    */
    const tableFactory = this.componentFactoryResolver.resolveComponentFactory(TableComponent);
    const viewContainerRef = this.tableHost.viewContainerRef;

    /**
     * clearing just in case something else was rendered before
     */
    viewContainerRef.clear();

    /**
     * now you will be able to access the methods and properties of your component after this
     */
    this.tableComponent = viewContainerRef.createComponent(tableFactory);
  }
}
@NgModule({
  declarations: [
    AppComponent,
    TableComponent,
    TableDirective
  ],
  imports: [
    BrowserModule
  ],
  entryComponents: [TableComponent],
  providers: [],
  bootstrap: [AppComponent]
})