javascript - TemplateRef 和更改检测
问题描述
最近我开始积极使用模板来定制我的 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>
然后点击“撤销”将不会触发源组件中的更改检测。弹出窗口中模板内的 {{balance}} 将被更新,但尽管它与原始余额组件中的变量相同 - 平衡不会知道此更改,直到某些东西触发了它的更改检测。
任何人都可以分享他们将如何解决这个问题的想法吗?OnPush 和模板是非常强大的工具,但我无法弄清楚在这种情况下将它们组合在一起的方法,因为 TemplateRef 没有对其原始组件的任何引用,只有它的 DOM 注释节点。
我可以强制将原始组件的 ChangeDetectorRef 传递给弹出服务,但我想为这样的任意情况提出一个解决方案。任何建议将不胜感激!
解决方案
好吧,我最终做的是创建一个指令:
<ng-template myDirective>
Content
</ng-template>
在那个指令中,我注入了TemplateRef
and ChangeDetectorRef
。这种方式不是提供TemplateRef
给我需要该模板的地方,而是提供ViewChild(MyDirective)
并myDirective.template
用作模板并调用该组件markForCheck()
上的更改检测器。ngAfterViewChecked()
推荐阅读
- go - 无法写入 cookie
- laravel - 带有plesk的Laravel + Vue App不加载所有资产
- python - 使用 python 更改数据集维度以绘制一个线时间序列数年
- python - 解析 XML 并写入一个大的 CSV 文件
- android - Kotlin - ArrayList 的自定义排序
- javascript - 推入打字稿正在循环中附加最后修改的对象
- php - php return 添加一个 span 类
- javascript - 如何在柏树中编写编辑图标的点击功能
- oracle - 防止 oracle 数据库计划作业在计划时间后运行
- r - 在我的数据集中添加分组变量的更好方法