Angular 內容投影出現 No provider for TemplateRef found 錯誤的單步除錯
阿新 • • 發佈:2022-03-05
問題描述
本文涉及到的程式碼位置:https://github.com/wangzixi-diablo/ngDynamic
我有一個能接受內容投影的 Angular Component:
使用如下程式碼消費這個 Component:
但是遇到執行時錯誤,如下圖所示。
點選 template.html:7:3
:
問題分析
丟擲該錯誤訊息的函式實現:
/** * Returns the value associated to the given token from the NodeInjectors => ModuleInjector. * * Look for the injector providing the token by walking up the node injector tree and then * the module injector tree. * * This function patches `token` with `__NG_ELEMENT_ID__` which contains the id for the bloom * filter. Negative values are reserved for special objects. * - `-1` is reserved for injecting `Injector` (implemented by `NodeInjector`) * * @param tNode The Node where the search for the injector should start * @param lView The `LView` that contains the `tNode` * @param token The token to look for * @param flags Injection flags * @param notFoundValue The value to return when the injection flags is `InjectFlags.Optional` * @returns the value from the injector, `null` when not found, or `notFoundValue` if provided */ function getOrCreateInjectable(tNode, lView, token, flags = InjectFlags.Default, notFoundValue)
第一個輸入引數 tnode
就是 p
節點本身:
token 指向 TemplateRef
:
解決方案
這個問題有幾種解決方案。
方案1
刪除 p 節點的自定義 Directive:
然後新增一個預設的內容投影:
解決方案2
刪除自定義 Directive 建構函式裡的 TemplateRef
依賴:
解決方案3
消費 zippy Component 時,直接傳入被投影的內容:
該內容會被投影到下圖第一行的 place holder:
解決方案4
消費 Component 時,通過 ng-template
+ 自定義 Directive
的方式指定被投影的內容:
通過 @ContentChild
TemplateRef
:
總結
渲染樹是實際的 DOM 渲染樹。 它與 Ivy
的邏輯樹不同,渲染樹必須考慮內容投影。 因此渲染樹裡的父/子關係不像邏輯檢視中那樣簡單。