<div *ngIf="true" myHighlight #tRefVar="myHighlight"></div> <div>tRefVar is {{tRefVar.foo}}</div>
即使* ngIf为真,我也得不到未定义的属性’foo’.如果我删除* ngIf,它工作正常!
我尝试使用Elvis运算符tRefVar?.foo来解决错误,但之后它永远不会随值更新.
https://plnkr.co/edit/5rsXygxK1sBbbkYdobjn?p=preview
我究竟做错了什么?
A variable declared inside of an *ngIf cannot be used outside of the
*ngIf
https://github.com/angular/angular/issues/6179#issuecomment-233374700
Only the opposite way (i.e. declare a variable inside of *ngIf and use
it outside of *ngIf) is not working,and won’t work by design.
https://github.com/angular/angular/issues/6179#issuecomment-233579605
为什么会这样?
1)没有* ngIf
我们来看看这个模板
<h2 myHighlight #tRefVar="myHighlight">tRefVar is {{tRefVar.foo}}</h2> <div>tRefVar is {{tRefVar?.foo}}</div>
angular将为此创建以下viewDefinition:
function View_App_0(_l) { return jit_viewDef1(0,[(_l()(),jit_textDef2(null,['\n '])),(_l()(),jit_elementDef3(0,null,2,'h2',[['myHighlight','']],null)),jit_directiveDef4(16384,[['tRefVar',4]],jit_HighlightDirective5,[jit_ElementRef6],null),['tRefVar is ',''])),1,'div',[],['\n ']))],function(_ck,_v) { var currVal_0 = jit_nodeValue7(_v,2).foo; _ck(_v,3,currVal_0); var currVal_1 = ((jit_nodeValue7(_v,2) == null)? null: jit_nodeValue7(_v,2).foo); _ck(_v,6,currVal_1); }); }
这里没有嵌入式视图.一体化View_App_0.我们可以在这里看到我们的表达式{{tRefVar?.foo}}
var currVal_1 = ((jit_nodeValue7(_v,2).foo);
它从索引为2的节点获取值
jit_directiveDef4(16384,'']))
在同一视图中声明的
2)使用* ngIf
然后让我们按如下方式更改模板
<h2 *ngIf="true" myHighlight #tRefVar="myHighlight">tRefVar is {{tRefVar.foo}}</h2> <div>tRefVar is {{tRefVar?.foo}}</div>
输出将如下
function View_App_1(_l) { return jit_viewDef1(0,jit_elementDef2(0,jit_directiveDef3(16384,jit_HighlightDirective4,[jit_ElementRef5],jit_textDef6(null,'']))],1).foo; _ck(_v,currVal_0); }); } function View_App_0(_l) { return jit_viewDef1(0,['\n'])),jit_anchorDef8(16777216,View_App_1)),jit_NgIf9,[jit_ViewContainerRef10,jit_TemplateRef11],{ngIf:[0,'ngIf']},_v) { var currVal_0 = true; _ck(_v,currVal_0); },_v) { var _co = _v.component; var currVal_1 = ((_co.tRefVar == null)? null: _co.tRefVar.foo); _ck(_v,5,currVal_1); }); }
Angular创建了嵌入式视图View_App_1,分别为View_App_0.我们的表达式{{tRefVar?.foo}}已经变成了
var currVal_1 = ((_co.tRefVar == null)? null: _co.tRefVar.foo);
它只是因为组件属性,因为没有节点会在View_App_0中引用此模板变量.它已进入嵌入式视图View_App_1
var currVal_0 = jit_nodeValue7(_v,1).foo;
所以我们不能引用在嵌入视图之外的嵌入视图中声明的模板变量.
怎么解决?
1)使用[hidden]或css类而不是* ngIf的可见性标志
2)在嵌入视图中将表达式移动到声明tRefVar的位置
<ng-container *ngIf="true"> <h2 myHighlight #tRefVar="myHighlight">tRefVar is {{tRefVar.foo}}</h2> <div>tRefVar is {{tRefVar?.foo}}</div> </ng-container>
3)使用@ViewChild,因为它将代表组件属性.或者使用@ViewChildren