将模板引用变量绑定为属性指令类型

Posted

技术标签:

【中文标题】将模板引用变量绑定为属性指令类型【英文标题】:Bind template reference variable as an attribute directive type 【发布时间】:2018-09-01 14:59:01 【问题描述】:

我正在构建一个属性指令,它应该获取几个模板,这些模板又应该包含用于过滤的额外数据,这些数据稍后将用于选择所需的模板。 所以我对 TemplatePortalDirective 进行了如下扩展:

@Directive(
  selector: "[filter]ng-template"
)
export class FilterableTemplateDirective extends TemplatePortalDirective 

  @Input() filter: string;

  constructor(templateRef: TemplateRef<any>, viewContainerRef: ViewContainerRef
  
    super(templateRef, viewContainerRef);
  

我的属性指令,名为TemplateSelector 有一个@Input,它也用作属性选择器:

@Directive(
  selector: "[templateSelector]"
)
...
@Input("templateSelector") templates: FilterableTemplateDirective[]

现在,假设我有以下模板:

<div templateSelector="[templateA, templateB]"></div>
<ng-template filter="div[data-type-a]" #templateA>
...
</ng-template>
<ng-template filter="div[data-type-b]" #templateB>
...
</ng-template>

所以,当我尝试从TemplateSelector 中的方法访问this.templates 时,我得到了数组,但它的类型是TemplateRef,即纯ng-template,没有额外的字段,虽然当我调试时我看到FilterableTemplateDirective 被构造了两次,在分配模板的数组之前,并且filter 也被分配了,尽管过滤器的分配发生在数组的分配之后模板。 我试图在构建数组时进行强制转换,如下所示:

<div templateSelector="[templateA as FilterableTemplateDirective, templateBtemplateA as FilterableTemplateDirective]"></div>

左右:

<div templateSelector="[<FilterableTemplateDirective>templateA, <FilterableTemplateDirective>templateBtemplateA]"></div>

两者都没有成功,应用程序只是崩溃,说它期待数组的结尾而不是 as 或尖括号...

【问题讨论】:

【参考方案1】:

好吧,现在看来答案是显而易见的,而且是浮于表面——只需在Directive decorator 上添加exportAs 属性,然后将引用分配给模板引用变量,与@987654323 非常相似@...

【讨论】:

【参考方案2】:

如果您的模板具有灵活性,那么您可以使用@ContentChildren 实现您想要的效果,如下所示:

<div templateSelector>
  <ng-template filter="div[data-type-a]">
    ...
  </ng-template>
  <ng-template filter="div[data-type-b]">
    ...
  </ng-template>
</div>

还有你的templateSelector 指令:

@Directive(
  selector: "[templateSelector]"
)

...

@ContentChildren(FilterableTemplateDirective) 
templates: QueryList<FilterableTemplateDirective>;

当使用模板变量标记元素时,你会受到限制,因为你无法告诉 Angular 你想从那个元素中得到什么。使用 @ContentChildren@ContentChild@ViewChild@ViewChildren 等模板查询,您可以灵活地告诉 Angular 是否需要来自它的指令/组件,或 ElementRef,或 ViewContainerRef(以及也许其他一些令牌)。

【讨论】:

是的,绝对是一种选择,但它不是灵活性问题,而是逻辑问题,如果可能的话,我更愿意将模板留在目标元素之外......

以上是关于将模板引用变量绑定为属性指令类型的主要内容,如果未能解决你的问题,请参考以下文章

使用绑定和模板指令

JVM方法的动态与静态绑定机制

JVM方法的动态与静态绑定机制

error C2662 无法将左值绑定到右值 —— 变量永远是左值,即使它的类型为右值引用

Vue模板语法

将绑定传递给类型属性包装器的变量 - 失去基础类型