当前位置: 首页 > Web前端 > JavaScript

Angularcontentprojectioncontentprojection关于条件渲染问题的单步调试

时间:2023-03-27 11:42:59 JavaScript

问题描述本文涉及的代码位置:https://github.com/wangzixi-d...ng-container和ngTemplateOutlet的使用.这里需要接受一个TemplateRef类型的输入:content.templateRef赋值在哪里?使用ContentChild的内容查询:在运行时,content的值是应用了ZippyContentDirective的ng-template表示的TemplateRef实例。这个Directive对应的selector是:appExampleZippyContent,所以就是下图中的template:我期望最后运行的时候能看到上图中template变量的值投影到app-example-zippy页面上的内容。然而实际结果是:控制台报错:ERRORTypeError:Cannotreadpropertiesofundefined(reading'templateRef')atZippyComponent_div_1_Template(template.html:3:19)atexecuteTemplate(core.js:7511:9))在refreshView(core.js:7380:13)在refreshEmbeddedViews(core.js:8481:17)在refreshView(core.js:7404:9)在refreshComponent(core.js:8527:13)在refreshChildComponents(core.js:7186:9)atrefreshView(core.js:7430:13)atrefreshComponent(core.js:8527:13)atrefreshChildComponents(core.js:7186:9)问题分析点击template.html进入具体代码locationthatcausedtheerror:自动定位到上图中的第三行:content.templateRef,content的值在运行时是undefined,因为试图访问未定义的templateRef属性而报错。content的值为空,说明下图中的内容查询执行失败了:@ContentChild(ZippyContentDirective)我在这个自定义Directive的构造函数中设置了断点,但是在运行时根本没有触发断点,这只能说明Angular框架根本不识别Directive:原因是自定义Directive所在的NgModule定义的声明区域中没有添加自定义Directive。取消上图中21行代码的注释后,立即调用自定义Directive的构造函数:注意这里的调用上下文:当自定义Directive被添加到NgModule的声明区时,一旦模板解析逻辑检测到Directive,它会被Angular的依赖注入相关的框架代码调用,自动生成一个Directive实例:if(isDirectiveHost(tNode)){createDirectivesInstances(tView,lView,tNode);}总结本文采用的自定义Directive本质上是一个锚点,用于定位内容将要投影的模板实例TemplateRef。使用TemplateRef,组件可以使用ngTemplateOutlet指令或ViewContainerRef方法createEmbeddedView()呈现引用的内容。