Ember:模型更改时重新渲染路线的模板

Posted

技术标签:

【中文标题】Ember:模型更改时重新渲染路线的模板【英文标题】:Ember: Re-render a route's template when the model changes 【发布时间】:2018-04-20 06:39:22 【问题描述】:

我注意到当模型更改时,路线不会重新渲染(即transitionTo 相同的路线与不同的模型)。我在特定页面上设置了一些 jQuery 插件,当模型更改时我需要它们重新渲染,因此它显示为新页面。

有没有办法做到这一点?也许通过观察模型的 ID 并以某种方式重新渲染路线?

提前致谢

【问题讨论】:

我不确定我是否理解这个问题。你的意思是你希望你的路线在模型改变时重新渲染?所以你想做一些类似model.save()的事情,然后你想让页面重新加载以重新运行你的jQuery插件?你的 jQuery 插件有钩子吗?你能做类似model.save().then(() => /* jQueryPlugin.refresh() /* ) 的事情吗? 我只需要在输入路由时重新渲染模板即可,不管之前的路由如何。当前的 Ember 功能是,如果您使用不同的模型转换到相同的路由,则只会更新数据绑定 - 不会重新渲染视图。 啊啊,对不起,我的错。我以为您是在说数据绑定出于某种原因没有更新。我现在知道了。您不仅希望更新数据绑定,还希望重新渲染整个模板。 【参考方案1】:

我有一个ember twiddle,我相信它可以满足您的要求,但首先我想说的是,没有直接的方法可以满足您的要求,因为它与 相反SPA 的设计目的是什么

数据绑定(不刷新视图)通常是 SPA 的一大优势,SPA 努力避免不惜一切代价强制重新加载/刷新/重新渲染视图。我花了一段时间才找到a 解决您的问题的方法,因为它似乎违反了 Ember 设计原则。甚至像 route refresh() 这样的钩子也是为了更新模型和绑定数据,而不是重新加载模板。

Although other people have asked 同样的问题之前,似乎大多数答案引导用户刷新整个视图。通常,刷新视图的理想是一个错误的假设。

按照前面的示例,我建议您的目标不应该是完全刷新模板,而是要弄清楚如何使您的 jQuery 插件更好地适应单页应用程序/客户端JS 友好的设计 并将其重新加载为路由生命周期的自然部分。

例如,也许插件可以在afterModel() 或类似的地方重新加载/重置/重新运行。

也就是说,我能够使用Ember.run.later() 完成您要求的操作(在我看来,这是一种黑客行为),这样我就可以使 if 块无效并强制重新呈现内容.请注意,这通常不是用户想要的,因为(除了设计原则原因)它会导致 UI 闪烁。

我有一个这样的组件。

/* will-rerender.hbs */
#if show
    yield
/if

它有一个像这样的JS文件。

/* will-rerender.js */
import Ember from 'ember';

export default Ember.Component.extend(
  show: false,

  didReceiveAttrs() 
    this._super(...arguments);

    /* 
      Ugly hack, but we need to reset `show` in
      a separate run loop in order to force the view
      to rerender.
    */

    this.set('show', false);

    Ember.run.later(() => 
      this.set('show', true);
    );
  
);

你可以这样调用它...

/* your template */
#will-rerender cacheKey=model.id
   ... your content to rerender ...
/will-rerender

每当model.id 更改时,组件将调用didReceiveAttrs() 导致show 无效并刷新视图。

顺便说一句,我认为使用link-to 而不是自己调用transitionTo 在模型之间切换的行为会更自然。

【讨论】:

谢谢你的例子,威尔。我认为可以通过说组件需要重新渲染的原因是它们实际上加载数据来更好地描述我的情况。其中一些是图表(Chart.js),它们自己获取数据,而不是从路线中获取给定数据。我认为您的解决方案仍然有效,但我想知道这种额外的见解是否会导致更优雅的解决方案 感谢您提供额外的上下文,亚当。如果最终目标是为图表重新加载数据,那么使用Chart.js APIs for updating data 怎么样?您可能会在组件或控制器中绑定一个操作来更新 Chart.js 数据数组。 请问,我确实成功地使用了更新数据 API,结合 ember-diff-attrs 和观察模型 ID 的计算函数。感谢您的帮助! 太棒了!很高兴听到你成功了,亚当。

以上是关于Ember:模型更改时重新渲染路线的模板的主要内容,如果未能解决你的问题,请参考以下文章

本地数组更改时如何重新渲染流星火焰模板?

在模型更改重新渲染时,一些嵌套属性会消失

Ember - 嵌套子路由在路由刷新/重新加载时丢失模型

如何在 react 中的新路由更改上使用 useEffect 重新渲染变量

在 emberjs 中重新渲染视图

如何在加载模型时在Ember中显示加载模板?