【问题标题】:*ngIf and local template variables*ngIf 和局部模板变量
【发布时间】: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 听起来像是解释

标签: angular interpolation


【解决方案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 方法。

【讨论】:

    猜你喜欢
    • 2019-01-05
    • 2017-10-17
    • 2020-01-01
    • 2017-12-28
    • 2018-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多