如何将模板引用变量与 ngIf 结合使用? [英] How do I combine a template reference variable with ngIf?
问题描述
<div *ngIf="true" myHighlight #tRefVar="myHighlight"></div><div>tRefVar 是 {{tRefVar.foo}}</div>
即使 *ngIf
为真,我也得到一个 Cannot read property 'foo' of undefined
.如果我删除 *ngIf
,它工作正常!
我尝试使用 Elvis 运算符 tRefVar?.foo
,它解决了错误,但它永远不会更新值.
这里没有嵌入的视图.一体化View_App_0
.我们可以在这里看到我们的表达式 {{tRefVar?.foo}}
var currVal_1 = ((jit_nodeValue7(_v,2) == null)? null: jit_nodeValue7(_v,2).foo);
它从索引为 2 的节点获取值
jit_directiveDef4(16384,[['tRefVar',4]],0,jit_HighlightDirective5,[jit_ElementRef6],null,null),(_l()(),jit_textDef2(null,['tRefVar is ','']))
在同一个视图中声明
2) 使用 *ngIf
然后让我们改变模板如下
<h2 *ngIf="true" myHighlight #tRefVar="myHighlight">tRefVar 是 {{tRefVar.foo}}</h2><div>tRefVar 是 {{tRefVar?.foo}}</div>
输出如下
function View_App_1(_l) {return jit_viewDef1(0,[(_l()(),jit_elementDef2(0,null,null,2,'h2',[['myHighlight','']],null,null,null,null,null)),jit_directiveDef3(16384,[['tRefVar',4]],0,jit_HighlightDirective4,[jit_ElementRef5],null,null),(_l()(),jit_textDef6(null,['tRefVar is ','']))],空,函数(_ck,_v){var currVal_0 = jit_nodeValue7(_v,1).foo;_ck(_v,2,0,currVal_0);});}函数 View_App_0(_l) {返回 jit_viewDef1(0,[(_l()(),jit_textDef6(null,['\n'])),(_l()(),jit_anchorDef8(16777216,null,null,1,null,View_App_1)),jit_directiveDef3(16384,null,0,jit_NgIf9,[jit_ViewContainerRef10,jit_TemplateRef11],{ngIf:[0,'ngIf']},null),(_l()(),jit_textDef6(null,['\n'])),(_l()(),jit_elementDef2(0,null,null,1,'div',[],null,null,null,null,null)),(_l()(),jit_textDef6(null,['tRefVar is ',''])),(_l()(),jit_textDef6(null,['\n ']))],函数(_ck,_v){var currVal_0 = true;_ck(_v,2,0,currVal_0);},函数(_ck,_v){var _co = _v.component;var currVal_1 = ((_co.tRefVar == null)? null: _co.tRefVar.foo);_ck(_v,5,0,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
的嵌入视图中
<h2 myHighlight #tRefVar="myHighlight">tRefVar 是 {{tRefVar.foo}}</h2><div>tRefVar 是 {{tRefVar?.foo}}</div></ng-容器>
3) 使用 @ViewChild
因为它将代表组件属性.或者使用 @ViewChildren
<div *ngIf="true" myHighlight #tRefVar="myHighlight"></div>
<div>tRefVar is {{tRefVar.foo}}</div>
Even though the *ngIf
is true, I get a Cannot read property 'foo' of undefined
. If I remove the *ngIf
, it works fine!
I tried using the Elvis operator tRefVar?.foo
, which resolved the error, but then it never updates with the value.
https://plnkr.co/edit/5rsXygxK1sBbbkYdobjn?p=preview
What am I doing wrong?
As Tobias Bosch said
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
Why is it so?
1) Without *ngIf
Let's see at this template
<h2 myHighlight #tRefVar="myHighlight">tRefVar is {{tRefVar.foo}}</h2>
<div>tRefVar is {{tRefVar?.foo}}</div>
angular will create the following viewDefinition
for that:
function View_App_0(_l) {
return jit_viewDef1(0,[(_l()(),jit_textDef2(null,['\n '])),(_l()(),jit_elementDef3(0,
null,null,2,'h2',[['myHighlight','']],null,null,null,null,null)),jit_directiveDef4(16384,
[['tRefVar',4]],0,jit_HighlightDirective5,[jit_ElementRef6],null,null),(_l()(),
jit_textDef2(null,['tRefVar is ',''])),(_l()(),jit_textDef2(null,['\n '])),
(_l()(),jit_elementDef3(0,null,null,1,'div',[],null,null,null,null,null)),(_l()(),
jit_textDef2(null,['tRefVar is ',''])),(_l()(),jit_textDef2(null,['\n ']))],
null,function(_ck,_v) {
var currVal_0 = jit_nodeValue7(_v,2).foo;
_ck(_v,3,0,currVal_0);
var currVal_1 = ((jit_nodeValue7(_v,2) == null)? null: jit_nodeValue7(_v,2).foo);
_ck(_v,6,0,currVal_1);
});
}
there is no embedded view here. All in one View_App_0
. And we can see here our expression {{tRefVar?.foo}}
var currVal_1 = ((jit_nodeValue7(_v,2) == null)? null: jit_nodeValue7(_v,2).foo);
it takes value from node with index 2
jit_directiveDef4(16384,
[['tRefVar',4]],0,jit_HighlightDirective5,[jit_ElementRef6],null,null),(_l()(),
jit_textDef2(null,['tRefVar is ','']))
that declared in the same view
2) With *ngIf
Then let's change template as follows
<h2 *ngIf="true" myHighlight #tRefVar="myHighlight">tRefVar is {{tRefVar.foo}}</h2>
<div>tRefVar is {{tRefVar?.foo}}</div>
The output will be the following
function View_App_1(_l) {
return jit_viewDef1(0,[(_l()(),jit_elementDef2(0,null,null,2,'h2',[['myHighlight',
'']],null,null,null,null,null)),jit_directiveDef3(16384,[['tRefVar',4]],0,jit_HighlightDirective4,
[jit_ElementRef5],null,null),(_l()(),jit_textDef6(null,['tRefVar is ','']))],
null,function(_ck,_v) {
var currVal_0 = jit_nodeValue7(_v,1).foo;
_ck(_v,2,0,currVal_0);
});
}
function View_App_0(_l) {
return jit_viewDef1(0,[(_l()(),jit_textDef6(null,['\n'])),(_l()(),jit_anchorDef8(16777216,
null,null,1,null,View_App_1)),jit_directiveDef3(16384,null,0,jit_NgIf9,[jit_ViewContainerRef10,
jit_TemplateRef11],{ngIf:[0,'ngIf']},null),(_l()(),jit_textDef6(null,['\n'])),
(_l()(),jit_elementDef2(0,null,null,1,'div',[],null,null,null,null,null)),(_l()(),
jit_textDef6(null,['tRefVar is ',''])),(_l()(),jit_textDef6(null,['\n ']))],
function(_ck,_v) {
var currVal_0 = true;
_ck(_v,2,0,currVal_0);
},function(_ck,_v) {
var _co = _v.component;
var currVal_1 = ((_co.tRefVar == null)? null: _co.tRefVar.foo);
_ck(_v,5,0,currVal_1);
});
}
Angular created embedded view View_App_1
apart to View_App_0
. And our expression {{tRefVar?.foo}}
has turned into
var currVal_1 = ((_co.tRefVar == null)? null: _co.tRefVar.foo);
it just becames component property because there is no node that will reference to this template variable in View_App_0
. It's gone to embedded view View_App_1
var currVal_0 = jit_nodeValue7(_v,1).foo;
So we cannot refer to template variable that has been declared in embedded view outside of embedded view.
How to solve it?
1) Use visibility flag like [hidden]
or css class instead of *ngIf
2) Move your expression inside embedded view where tRefVar
is declared
<ng-container *ngIf="true">
<h2 myHighlight #tRefVar="myHighlight">tRefVar is {{tRefVar.foo}}</h2>
<div>tRefVar is {{tRefVar?.foo}}</div>
</ng-container>
3) Use @ViewChild
because it will represent component property. Or use @ViewChildren
这篇关于如何将模板引用变量与 ngIf 结合使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!