【问题标题】:Angular2 TemplateRef SelectorAngular2 TemplateRef 选择器
【发布时间】:2017-04-03 05:47:58
【问题描述】:

在我的datatable project 中,开发人员可以在表格声明中声明模板以用于标题单元格和正文单元格。

<datatable>
    <datatable-column name="Name">
        <template let-column="column">
            Header: {{column.name}}
        </template>
        <template let-value="value">
            Hi: <strong>{{value}}</strong>
        </template>
    </datatable-column>
    <datatable-column name="Age">
        <datatable-body-template let-value="value">
            I'm: <strong>{{value}}</strong> old
        </datatable-body-template>
    </datatable-column>
</datatable>

在上面的例子中,第一个模板是标题单元格模板,第二个是正文单元格模板,顺序很重要。如果你只声明一个模板,它只会做body cell模板。您可以看到当前是如何完成的here

我目前确实允许您通过 InputTemplateRefs 传递给 column 指令,但这种方法还可以,但作为 API 使用者,组件定义中的声明性模板是一种更简洁的方法。

还值得注意的是,不能通过 #body#header 之类的方式进行命名,因为您可以拥有多个列,从而使名称不唯一。

这个 DSL 不是很直观,因为它不是很明确的,它取决于顺序。 ng-content 允许您输入选择器属性,我想知道使用模板完成类似操作的最佳方法是什么?所以像:

<datatable>
    <datatable-column name="Name">
        <datatable-header-template let-column="column">
            Header: {{column.name}}
        </datatable-header-template>
        <datatable-body-template let-value="value">
            Hi: <strong>{{value}}</strong>
        </datatable-body-template>
    </datatable-column>
</datatable>

我正在四处寻找是否可以覆盖TemplateRef,但我不确定这是否是个好主意。

说了这么多……我的问题是,我怎样才能完成命名选择器模板引用?

【问题讨论】:

    标签: angularjs angular angular2-template


    【解决方案1】:

    您可以将模板传递给输入

    <template #header let-column="column">
        Header: {{column.name}}
    </template>
    
    <template #body let-value="value">
        Hi: <strong>{{value}}</strong>
    </template>
    
    <datatable>
        <datatable-column name="Name" [header]="header" [column]="body"></datatable-column>
    </datatable>
    

    更新

    也可以通过这些添加模板变量和查询

    <datatable>
      <template let-column="column" #header>
        header1
      </template>
      <template let-value="value" #column>
        column1
      </template>
    
      <template let-value="value" #column>
        column2
      </template>
    

      @ContentChildren('header', {read: TemplateRef}) headerTemplates:QueryList<TemplateRef>;
      @ContentChildren('column', {read: TemplateRef}) columnTemplates:QueryList<TemplateRef>;
    

    或使用指令。这种方法允许传递额外的信息

    @Directive({
      selector: '[header]';
    })
    class HeaderTemplate {
      constructor(private template:TemplateRef) {};
    
      @Input() header:String;
    }
    
    @Directive({
      selector: '[column]';
    })
    class ColumnTemplate {
      constructor(private template:TemplateRef) {};
    
      @Input() column:String;
    }
    
    <datatable>
      <template let-column="column" header="1">
        header1
      </template>
      <template let-value="value" column="1">
        column1
      </template>
    
      <template let-value="value" column="2">
        column2
      </template>
    
    </datatable>
    
    @ContentChildren(HeaderTemplate) headerTemplates:QueryList<HeaderTemplate>;
    @ContentChildren(ColumnTemplate) columnTemplates:QueryList<ColumnTemplate>;
    

    headerTemplate / columnTemplatetemplateheader / column 属性允许您访问模板和传递的值(可以有额外的 @Inputs(),但匹配选择器的最容易使用)。

    Plunker example

    【讨论】:

    • 啊,是的,我目前允许这样做,但在我看来,它作为 api 消费者并不是很干净。此外,如果您希望每列有多个自定义模板,它会变得更加混乱。我将更新演示以显示这一点。
    • 只是一个旁注,君特你是个野兽!在 Stack Overflow 上成为 Angular 2 的 Jon Skeet 的好机会;)
    • 在我看到toggl.com/programming-princess 之后,我知道我必须成为 SO 上的第一名才能以这种方式被提及:D
    • 更新我的答案。
    • 再次感谢@GünterZöchbauer - 我采纳了你的建议,效果很好! github.com/swimlane/angular2-data-table/blob/2.1.3/src/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-18
    • 1970-01-01
    • 2017-01-16
    • 1970-01-01
    • 1970-01-01
    • 2016-07-20
    • 1970-01-01
    相关资源
    最近更新 更多