关于 Angular view Query 的 id 选择器问题的单步调试

问题描述
我有这样一个 Angular Component,模板文件如下:@Component({selector: 'example-app',template: `<pane id="1" *ngIf="shouldShow"></pane><pane id="2" *ngIf="!shouldShow"></pane>
`,})
然而运行时没有得到期望的结果,报错:
ERROR TypeError: Cannot read properties of undefined (reading 'id')at ViewChildComp.set (ng-content.component.ts:57:27)at ViewChildComp_Query (template.html:3:5)at executeViewQueryFn (core.js:8758:5)at refreshView (core.js:7437:13)at refreshComponent (core.js:8527:13)at refreshChildComponents (core.js:7186:9)at refreshView (core.js:7430:13)at refreshComponent (core.js:8527:13)at refreshChildComponents (core.js:7186:9)at refreshView (core.js:7430:13)

问题分析
我们点击上图高亮的 template.html
调用栈:
来到我们自己 Component 的模板文件,因为这是一个内联到 Component 里的模板,所以显示为 template.html
:

通过单步调试,能发现在 refreshView
里,执行 view query
的入口逻辑:


根据关键字 view query
查询 Angular 官网,发现在 view query 里使用 id 选择器的正确语法,并不是直接查询 HTML 元素的 id 属性,而是需要在 HTML 元素或者 ng-template
里使用符号 #
指定一个 id,然后将这个 id 传入 @ViewChild
:


修改之后的运行效果:

总结
view query 在父 Component 需要访问其子 Component 的场景下特别有用。
假设有一个 alert Component:
在我们的父 Component 里,可以定义 AlertComponent 的多个实例:
我们可以使用 @ViewChildren 装饰器从宿主视图中抓取元素。@ViewChildren 装饰器支持指令或组件类型作为参数,或模板变量的名称。当参数是组件/指令时,返回值将是组件/指令实例。
上面例子的 console.log 语句会打印 AlertComponent 的实例:

版权声明: 本文为 InfoQ 作者【Jerry Wang】的原创文章。
原文链接:【http://xie.infoq.cn/article/8e96f78b92090214b83f196a6】。文章转载请联系作者。
评论