*ngIf 和局部模板变量

Posted

技术标签:

【中文标题】*ngIf 和局部模板变量【英文标题】:*ngIf and local template variables 【发布时间】:2016-08-07 03:38:12 【问题描述】:

有人可以解释以下行为背后的原因吗?

假设我们有一个 Angular 2 组件,它有一个 _model 对象。然后在模板中我们有这个:

<form>
    <input type="text" class="form-control" required [(ngModel)]="_model.firstName" ngControl="test2"  #myInput >
    <br>Class: myInput?.className
</form>

_model 从一开始就可以在 ngOnInit() 中从头开始创建。输入字段已正确填充 _model.firstName 变量和以下行:

&lt;br&gt;Class: myInput?.className

在模板中正确呈现以下内容:

Class: form-control ng-untouched ng-pristine ng-invalid.

到目前为止一切顺利。让我困惑的是,当我添加 *ngIf 并将输入字段更改为

<input *ngIf="_model" type="text" class="form-control" required [(ngModel)]="_model.firstName" ngControl="test2"  #myInput >

双花括号插值停止工作,因为显然本地 myInput 变量没有被初始化,即使代码中没有其他任何更改,_model object 仍然在 onNgInit() 中创建并且输入字段仍在工作适当地。 myInput?.className 唯一呈现的是

Class:

有人可以解释发生了什么和/或为我指出正确的文档吗?

编辑:

这是一个Plunker,显示了相关问题。

创建错误报告https://github.com/angular/angular/issues/8087

【问题讨论】:

你的 _model 是布尔值吗? 刚刚在我的应用程序中测试过,我可以重现您的问题。在您添加*ngIf 后,不知何故#myInput 得到undefined。这感觉像是一个 angular2 错误,或者必须有人想出一个很好的解释。 不过,您可以使用@ViewChild('myInput') myInputRef : ElementRef;Class: myInputRef?.nativeElement?.className 来获取元素,但这感觉不太合适 @GünterZöchbauer 假设我们使用ngFor 指令而不是ngIf,命名一个元素并在ngFor 上下文之外使用该名称是没有意义的(因为可能多个具有该名称的元素)。这里也是如此,考虑following,元素的名称在结构指令的上下文中可用,但不在它之外。这是有道理的,因为 Angular 无法知道特定指令是否会重复他的模板。 @tchelidze 听起来像是解释 【参考方案1】:

我们可以在同一个元素、兄弟元素或任何子元素上引用本地模板变量。 -- ref

*ngIf 变为/扩展为

<template [ngIf]="_model">
    <input type="text" class="form-control" required [(ngModel)]="_model.firstName"
     ngControl="test1" #myInput>
</template>

所以局部模板变量#myInput 只能在模板块内被引用(即兄弟元素和/或子元素)。因此,您必须将任何想要引用本地模板变量的 html 放入模板中:

<template [ngIf]="_model">
   <input type="text" class="form-control" required [(ngModel)]="_model.firstName"
    ngControl="test1"  #myInput >
   <br>Class (this works): myInput?.className
</template>

Plunker


如果您需要在模板块之外显示与输入相关的内容,请使用@ViewChildren('myInput') list:QueryList&lt;ElementRef&gt;,然后订阅更改:

ngAfterViewInit() 
   this.list.changes.subscribe( newList =>
      console.log('new list size:', newList.length)
   )

在API doc 中查看更多 QueryList 方法。

【讨论】:

以上是关于*ngIf 和局部模板变量的主要内容,如果未能解决你的问题,请参考以下文章

将 ngFor 变量传递给 ngIf 模板

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

角度模板 ngif 在重新加载页面之前不起作用

没有模板局部变量的Angular 4访问模板元素

没有 TemplateRef 的提供者! (NgIf -> 模板参考)

为模板中的变量赋值 - Angular7