问题描述本文设计的代码仓库:https://github.com/wangzixi-d...hostComponent:我是#paramTemplate中的div标签
我期望id是paramTemplate的传递给子组件的模板实例:app-template-input。但是,运行时Chrome控制台报错:NoneoftheseerrorsarewithinthecodeIwrote:ERRORTypeError:templateRef.createEmbeddedViewisnotafunctionatViewContainerRef.createEmbeddedView(core.js:10190:45)atNgTemplateOutlet.ngOnChanges(ng_template_outlet.ts:65:28)atNgTemplateOutlet.rememberChangeHistoryAndInvokeOnChangesHook(core.js:2373:14)atcallHook(core.js:3285:14)atcallHooks(core.js:3251:17)atexecuteInitAndCheckHooks(core.js):3203:9)atrefreshView(core.js:7395:21)atrefreshComponent(core.js:8527:13)atrefreshChildComponents(core.js:7186:9)atrefreshView(core.js:7430:13)问题从调用栈ViewContainerRef.createEmbeddedV分析iew开始分析,设置断点,开始调试:刷新页面,断点触发:查看变量templateRef,发现其值为字符串。但是接下来的语句需要调用templateRef的createEmbeddedView方法。显然,string类型的变量在其原型链上是不可能有这个方法的,所以报错。我们注意到当前的调用栈发生在ngTemplateOutlet的ngOnChanges方法中。查看app-template-input的实现,发现@Input接收到的数据类型是TemplateRef,因为只有这个类型定义了createEmbeddedView方法。在我们的实现中,一个字符串被错误地传递给它。解决方法是给属性inputTemplate加上一对方括号,使用表达式绑定语法,这样paramTemplate就会作为表达式执行,导致第48行的paramTemplate实例被传递给@Input:最后,问题是解决了:这里总结一下我们在ng-container中包裹了一个结构指令*ngTemplateOutlet。请参阅应用程序模板输入的实现。任何消费TemplateInputComponent的父Component都需要给第18行的@Input赋值一个模板实例,赋值语法如下:看来赋给inputTemplate的contentparamTemplate是一个字符串,但它实际上是一个表达式。最终生成的源码:这里使用*ngTemplateOutlet动态生成一个模板实例。也就是说,ng-template用#定义的id是和ng-container、*ngTemplateOutlet一起使用的。