为什么这条路线的模型在 3 个案例中只有 2 个被更新? - Ember.js 2.3

Why is this Route's model updated in only 2 of 3 cases? - Ember.js 2.3

我正在使用 Ember.js 2.3。我有一个 parent Route 看起来像这样:

App.AppRoute = Ember.Route.extend
  model: ->
    Ember.RSVP.hash
      projects: @store.findAll "project"
      clients: @store.findAll "client"
      consultants: @store.findAll "consultant"
      practiceAreas: @store.findAll("practice_area").then (practice_areas) ->
        practice_areas.sortBy "displayName"

我有一个 child Route 看起来像:

App.AppProjectRoute = Ember.Route.extend
  model: (params) ->
    hash = @modelFor "app"
    hash["project"] = @store.findRecord "project", params.project_id
      .then (p) -> p
    hash["workWeeks"] = @store.query "work-week", project_id: params.project_id
      .then (weeks) -> weeks
    console.log _.keys hash
    Ember.RSVP.hash hash

child Route 的模板包含:

  <hr/>
  {{add-consultant project=model.project consultants=model.consultants addConsultant="didAddConsultant"}}
</div>

然后 add-consultant 组件包含计算的 属性:

remainingConsultants: Ember.computed "project", "project.consultants.[]", "consultants.[]", ->
  already_involved = @get "project.consultants"
  remaining        = @get "consultants"

  already_involved.forEach (ai) ->
    remaining = remaining.reject (r) -> r.get("id") is ai.get("id")

  remaining.sortBy "displayName"

案例一

当我直接导航到一个项目时,例如 http://localhost/#/app/project/27Routes model 挂钩正确地向服务器查询数据并呈现模板和组件。

案例二

当我直接导航到项目时,然后手动更改 URL 中的项目 ID(比如从 http://localhost/#/app/project/27http://localhost/#/app/project/28 并按 EnterRoute model 钩子更新,模板和组件正确重新渲染。

案例三

但是 - 这是我的困惑 - 通过单击 link 导航到项目(例如,从使用 {#link-to} 帮助器的项目列表) - 即使我第一次访问该页面与案例 1 或案例 2 一样成功,然后立即导航回同一个项目,我收到错误消息:

TypeError: already_involved is undefined

再往深看,原来@get "project"本身是未定义的

使用 {#link-to} 而不是 "direct" 导航有何不同?这是我在定义路由模型层次结构时犯的错误吗?我是否缺少某种事件挂钩?


编辑 1: 如果有更智能或更惯用的方式来定义这些类型的分层 model 挂钩,也许可以避免这个问题?

编辑 2: Router

this.route "app", ->
  this.route "projects"
  this.route "project", path: "/project/:project_id"

link-to 助手或 transitionTo/transitionToRoute 触发的转换有两个 "modes"。过渡可以触发模型挂钩(beforeModelmodelafterModel),也可以不触发。

要跳过模型挂钩,您可以将对象传递给转换,例如{{link-to "Profile" user}}。 Ember.js 将此解释为您已经拥有必要的信息,因此跳过会加载所述信息的挂钩。

不过,要强制模型挂钩,您可以将字符串或整数传递给转换,例如{{link-to "Profile" 1}}{{link-to "Profile" user.id}}。这将使用传递给转换的值来填充路由的动态段,Ember.js 将其解释为尚未加载的必要数据,从而触发挂钩。

由于您的模型挂钩 returns 一个散列,因此强制挂钩以便正确加载所有内容是有利的。

您可以参考 documentation for the model hook 了解更多信息。