【问题标题】:Ember.js 2.2 - How to update Route model from a Component?Ember.js 2.2 - 如何从组件更新路由模型?
【发布时间】:2016-04-20 10:00:48
【问题描述】:

使用 Ember 2.2.0,我有一条路线:

Dash.BacklogReportsRoute = Ember.Route.extend
  model: ->
    @store.queryRecord "report", newest: true

和一个组件:

Dash.BacklogReportComponent = Ember.Component.extend
  report: null
  actions:
    generate: ->
      # Send the request.
      $.ajax
        type: "post",
        url: "/reports/generate/#{new Date().getFullYear()}",
        success: =>
          # Update the model.
          # TODO - how to reload the model in place? Or at least just refresh
          # the Route so we don't have to reload the entire app.
          window.location.reload()

其中包括作为模板的一部分:

<p>
  Report was generated {{report.timestamp}}.
</p>

其中timestamp 是报告模型上的计算属性。


Route 的模型是最新的 Report 对象,并且通过 POST generate 操作导致服务器创建更新的(因此更新的)报告。我想更新那个 [较新] 报告的时间戳。

我的问题是,在 Ember 2 中,我怎样才能让 Route 自行刷新? 我是 Ember 新手,所以我不确定是否可以直接从内部访问 Route一个组件(或者如果我可以,如果这是个好主意)。我不认为仅仅重新加载模型会起作用,因为在成功 POST 之后,@store.queryRecord "report", newest: true 将返回与加载页面时不同的模型(即具有不同 id 的记录)。 POST之后的现有模型将相同。

或者,我非常乐意完全重新渲染路线(这是一个非常简单的页面)或再次转换到“这个”页面,但我不知道该怎么做。

现在我只是强制使用老式页面window.location.reload()


换个角度看,也许有一种更惯用的方法来解决 Ember 的这个问题。

我是否应该使用 Route 加载所有(或部分)报告,并在 POST 之后强制刷新该集合?我看到 Enumerable 有一个 .firstObject 属性 - 这是一个计算属性(换句话说,如果我的 Routes 模型是一个报告集合并且我推到该集合的前面,那么该更改会通过.firstObject 传播吗?自动引用?)

【问题讨论】:

    标签: javascript ember.js routing refresh


    【解决方案1】:

    你实际上不能直接从组件访问路由。但这没问题,因为您可以使用动作来达到相同的效果。

    因此,首先您需要从组件中的 generate 操作发送一个操作:

    Dash.BacklogReportComponent = Ember.Component.extend
      report: null
      actions:
        generate: ->
          # Send the request.
          $.ajax
            type: "post",
            url: "/reports/generate/#{new Date().getFullYear()}",
            success: =>
              @sendAction('didGenerate')
    

    接下来,您需要在模板中关联操作,以便您的控制器/路由在被调用时得到通知:

    {{backlog-report report=report didGenerate='didGenerateReport'}}
    

    现在您可以在控制器或路由中“捕捉”该动作。我们将在另一条路线上执行此操作,以便我们可以刷新它:

    Dash.BacklogReportsRoute = Ember.Route.extend
      actions:
        didGenerateReport: ->
          @refresh()
      model: ->
        @store.queryRecord "report", newest: true
    

    抱歉,如果我在使用 CoffeScript 时犯了任何错误(有一段时间没有使用它)。还有其他可以改进的地方。一般来说,我不会将 ajax 调用放在组件中,如果可能的话,我会将它放在控制器/路由中并通过操作调用它(我只是有经验,最好避免将 ajax 调用放在组件中,尽管有是它的用例)。

    如果您还没有阅读所有ember guides,我通常会建议阅读。它们非常好,虽然您不会从第一次阅读就理解所有内容,但您至少会或多或少知道要寻找什么,或者什么是可能的。

    【讨论】:

    • 谢谢@awpeter,这太完美了。我已经阅读了(我认为是所有的)指南,但对组件操作依赖注入(根据guides.emberjs.com/v2.2.0/components/…)感到困惑,但这似乎更像是采取的方法。
    • 是的,没问题 :) 我只是建议你如果还没有这样做的话。也不必担心 Ember 很安静,但是一旦你掌握了它的窍门,它就真的很好用。这只是你必须克服的初始墙。
    【解决方案2】:

    如果您需要手动重新加载页面,确实应该有更好的方法。 Ember 与其他类似框架一样是 SPA(单页应用程序),并且在仅更新部分页面时非常有效地发挥其魔力。


    话虽如此,如果您想从controller/component 访问router,方法是向router 发送操作并处理action 中的更改。

    查看动作冒泡 https://guides.emberjs.com/v1.10.0/templates/actions/

    【讨论】:

      猜你喜欢
      • 2017-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-03
      • 1970-01-01
      • 2014-09-11
      相关资源
      最近更新 更多