最近我开始积极使用模板来自定义我的UI组件。我还使用OnPush变化检测策略来优化性能。如果我将模板传递给嵌套组件,一切顺利。用户操作会触发嵌套组件中的更改检测,并且它会一直移动到定义模板的原始组件,并在那里更改检测触发器,更新模板以及我在那里的任何其他逻辑。
但是如果我尝试使用模板制作弹出/警告/工具提示功能 - 我开始将树上的TemplateRef传递给弹出主机组件。因此,如果我对其执行任何操作 - 更改检测将无法到达模板的原点。因此,假设我在伪代码中有这个组件:
<p>Your balance: {{balance}}</p>
<ng-template #popup>
Your balance: {{balance}}
<button (click)="balance -= 100">Withdraw</button>
</ng-template>
如果我将此模板传递给位于DOM树中的弹出主机组件:
<main-component>
<balance></balance>
</main-component>
<popup-host></popup-host>
然后单击“Withdraw”将不会触发原点组件中的更改检测。弹出窗口中模板内的{{balance}}将会更新,但尽管它与原始余额组件中的变量相同 - 余额不会知道此更改,直到某些内容触发了其更改检测。
有人可以分享他们如何解决这个问题吗? OnPush和模板是非常强大的工具,但我无法弄清楚在这种情况下将它们组合在一起的方法,因为TemplateRef没有对其原始组件的任何引用,只有它的DOM注释节点。
我可以强制将原始组件的ChangeDetectorRef传递给弹出服务,但我想提出一个像这样的任意案例的解决方案。任何建议将不胜感激!
答案 0 :(得分:1)
嗯,我最终做的是创建一个指令:
<ng-template myDirective>
Content
</ng-template>
在该指令中,我注入了TemplateRef
和ChangeDetectorRef
。这样我就不会将TemplateRef
提供给我需要该模板的位置,而是ViewChild(MyDirective)
并使用myDirective.template
作为模板,并在markForCheck()
上的变更检测器上调用ngAfterViewChecked()
该组件。