Angular 基于自定义指令的内容投影 content projection 问题的单步调试

简介: Angular 基于自定义指令的内容投影 content projection 问题的单步调试

问题描述

本文涉及到的代码位置:https://github.com/wangzixi-diablo/ngDynamic

我有一个能接受内容投影的 Angular Component:

具体投影内容,通过 ng-container 和指令 ngTemplateOutlet 指定。

ngTemplateOutlet 的来源是 content,这个属性是 Component 通过下列 content query 得到的结果:

@ContentChild(ZippyContentDirective) content!: ZippyContentDirective;

从语义上讲,消费 app-example-zippy 的 Component 的 HTML 模板里,只有有 ng-template 元素设置有自定义指令 ZippyContentDirective 对应的 attribute selector,

则该 ng-template 里的内容会被自动投影到 app-example-zippy 内部。


然而运行时,我们观察不到上图高亮的第四行内容,而是在 console 里看到如下错误消息:


ERROR TypeError: Cannot read properties of undefined (reading ‘templateRef’)

at ZippyComponent_div_1_Template (template.html:3:19)

at executeTemplate (core.js:7511:9)

at refreshView (core.js:7380:13)

at refreshEmbeddedViews (core.js:8481:17)

at refreshView (core.js:7404:9)

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)


问题分析

content 内容为 undefined,说明 content query 执行失败了:


app-example-zippy 内部的 ng-template,使用的 attribute Directive 同ZippyContentDirective 定义的 selector 不一致,如下图所示:


纠正之后问题消失。

总结

Ivy 在进行渲染时,需要跟踪三种数据:Template、Logical Tree 和 Render Tree。在我们的许多数据结构中,为了简洁起见,这三个概念被缩写为 T、L 和 R 前缀。


模板是源代码的解析版本。它包含以 Ivy 指令和有关组件/指令的元数据的形式呈现模板的指令。如果您可以在源代码中找到它,那么模板数据结构中的相应字段也将出现。无论其中的代码是否已执行,模板信息都存在。例如,即使条件为假,*ngIf 后面的模板仍将具有此模板信息)。


在 Ivy 中,模板信息存储在 TView(以及 TData 和 TNode)数据结构中。这些数据结构一起提供了关于模板 Ivy 在运行时需要的所有静态信息。 静态这个词对于将其与另一个 Ivy 里重要的 Logic View概念相区分开。

相关文章
关于 Angular view Query 的 id 选择器问题的单步调试
关于 Angular view Query 的 id 选择器问题的单步调试
|
9月前
|
JavaScript
Angular 内容投影出现 No provider for TemplateRef found 错误的单步调试
Angular 内容投影出现 No provider for TemplateRef found 错误的单步调试
|
9月前
|
存储 JavaScript 前端开发
通过单步调试的方式学习 Angular 中 TView 和 LView 的概念
通过单步调试的方式学习 Angular 中 TView 和 LView 的概念
|
9月前
|
前端开发 JavaScript
通过单步调试的方式学习 Angular 中带有选择器的内容投影使用方式
通过单步调试的方式学习 Angular 中带有选择器的内容投影使用方式
|
2月前
|
存储 前端开发 API
浅谈 Angular 应用前端消息显示机制的一个实际需求
浅谈 Angular 应用前端消息显示机制的一个实际需求
|
2月前
|
设计模式 JavaScript 前端开发
什么是 Angular 应用里的 Custom provider
什么是 Angular 应用里的 Custom provider
|
2月前
|
JavaScript 前端开发 架构师
Angular进阶:理解RxJS在Angular应用中的高效运用
RxJS(Reactive Extensions for JavaScript)是JavaScript的一个响应式编程库,特别适用于处理异步数据流。
35 0
|
2月前
|
JavaScript 前端开发
Angular.js 应用中数据模式的删除操作实现
Angular.js 应用中数据模式的删除操作实现
|
2月前
|
存储 JavaScript 前端开发
Angular 应用 node_modules 子文件夹 @types 的作用介绍
Angular 应用 node_modules 子文件夹 @types 的作用介绍
|
7天前
|
JavaScript 前端开发 开发者
Angular框架:企业级Web应用的强大后盾
Angular,谷歌支持的JavaScript框架,因其组件化架构、双向数据绑定、依赖注入和路由系统,成为企业级Web开发首选。组件化促进代码重用,如`AppComponent`示例。双向数据绑定简化DOM操作,减少手动工作。依赖注入通过示例展示易管理依赖,提升测试性。路由则支持SPA开发,平滑页面过渡。Angular的特性增强了开发效率和应用质量,使其在Web开发领域保持领先地位。【6月更文挑战第25天】
15 2