【问题标题】:TemplateRef and change detectionTemplateRef 和更改检测
【发布时间】:2018-10-10 08:24:23
【问题描述】:

最近我开始积极使用模板来自定义我的 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 传递给弹出服务,但我想为这种任意情况提供解决方案。任何建议将不胜感激!

【问题讨论】:

  • 我们使用通用组件来弹出。这在服务内部被引用,并且 show 方法返回用户所做的操作。如果我们需要比这更复杂的东西,我们会创建一个单独的自定义组件并将所有逻辑放在那里。
  • 看看Material的Dialog服务
  • 是的,我也在我当前的代码中使用动态组件,但我想从它移到模板。我还将模板用于下拉菜单,例如自定义选择小部件,该下拉菜单以门户模式呈现,因此在这种情况下,模板是可行的方法,但这个普遍问题仍然存在。我自己提供了所有必要的变更检测器,将一切都连接起来,但我想提出一个通用的解决方案。

标签: javascript angular angular5


【解决方案1】:

好吧,我最终做的是创建一个指令:

<ng-template myDirective>
  Content
</ng-template>

在该指令中,我注入了TemplateRefChangeDetectorRef。这种方式不是将TemplateRef 提供给我需要该模板的地方,而是提供ViewChild(MyDirective) 并使用myDirective.template 作为模板并在该组件的ngAfterViewChecked() 上的更改检测器上调用markForCheck()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-06-13
    • 2011-09-18
    • 2018-04-14
    • 1970-01-01
    • 1970-01-01
    • 2012-03-24
    • 2012-05-26
    • 2011-06-30
    相关资源
    最近更新 更多