自定义 Angular 结构指令仅适用于星号语法

Posted

技术标签:

【中文标题】自定义 Angular 结构指令仅适用于星号语法【英文标题】:Custom Angular structural directive only works with asterisk syntax 【发布时间】:2019-01-22 23:23:08 【问题描述】:

我创建了一个 Angular 结构指令,但它仅适用于 * 语法,而不适用于“扩展”<ng-template> 语法。

快速reminder:

当你在结构指令前面加上星号时,例如*ngIf="xxx",模板编译器会扩展它,所以下面是等价的:

<p *ngIf="condition">
  Our heroes are true!
</p>

<ng-template [ngIf]="condition">
  <p>
    Our heroes are true!
  </p>
</ng-template>

所以我创建了自己的指令(基于 ngIf 源代码):

@Directive(
    selector: '[featureBoxLoader]'
)
export class FeatureBoxLoaderDirective 

    private _thenTemplateRef: TemplateRef<any>|null = null;

    constructor(private _viewContainer: ViewContainerRef, 
                private templateRef: TemplateRef<any>) 
    
        this._thenTemplateRef = templateRef;
    

    ngOnInit()
    
        alert('yes it works!');
        this._viewContainer.createEmbeddedView(this._thenTemplateRef,  $implicit:  numbers: [1, 2, 3]   );
    

该指令在我的模块中声明,当我像这样使用它时它工作正常:

  <div *featureBoxLoader>
     This is my feature box
  </div>

但是,当我这样做时,我得到一个错误:

 <ng-template [featureBoxLoader] let-data></ng-template>

错误是:

无法绑定到“featureBoxLoader”,因为它不是 'ng 模板'。 1. 如果 'featureBoxLoader' 是 Angular 指令,则将 'CommonModule' 添加到该组件的 '@NgModule.imports' 中。 2. 要允许任何属性添加“NO_ERRORS_SCHEMA”到该组件的“@NgModule.schemas”。

发生了什么事?很明显找到了,但我需要为let 使用&lt;ng-template&gt; 语法。

【问题讨论】:

【参考方案1】:

不同之处在于,在*ngIf 示例中,您提供了一个参数(以及ng_if directive implementation 中相应的@Input 参数)。

[ngIf]="condition"

当您只是在没有条件的情况下应用指令时,括号不是必需的。

所以正确的语法就是:

<ng-template featureBoxLoader let-data></ng-template>

【讨论】:

以上是关于自定义 Angular 结构指令仅适用于星号语法的主要内容,如果未能解决你的问题,请参考以下文章

在标签文本中附加星号的 Angular 指令

nuxt js中的自定义指令

Angular 2 中自定义指令

如果模板包含 *ngIf,Angular 自定义结构指令无法重建 ViewContainer

自定义指标仅适用于急切执行

犰狳的自定义 natvis 文件仅适用于 resharper