【问题标题】:Nested resource route triggers parent resource route嵌套资源路由触发父资源路由
【发布时间】:2013-01-31 17:00:08
【问题描述】:

我的应用中有这样的路由器

TravelApi.Router.map ->
  @resource 'stars', ->
    @resource 'star', { path: '/:star_id' }

当我去http://localhost/#/stars 我在 Web 控制台中看到有一个请求

GET http://localhost:3000/stars

当我去http://localhost/#/stars/1 我在 Web 控制台中看到有两个请求

GET http://localhost:3000/stars

GET http://localhost:3000/stars/1

问题:为什么第二种情况有两个请求?


星星路线

TravelApi.StarRoute = Ember.Route.extend(
  model: (params) ->
    TravelApi.Star.find(params.star_id)
)

TravelApi.StarsRoute = Ember.Route.extend(
  model: ->
    TravelApi.Star.find()
)

还有我的模板: application.js.hbs.hamlbars

= hb "linkTo 'stars'" do
  stars
%div= hb 'outlet'

stars.js.hbs.hamlbars

%ul
  =hb "each star in controller" do
    %li<
      =hb 'star.name'

star.js.hbs.hamlbars

Star:
= hb 'name'

商店.js.coffee

TravelApi.store = DS.Store.create(
  revision: 11
  adapter: DS.RESTAdapter.create()
)

【问题讨论】:

  • 如果您在Store 中已经有该记录,它真的不应该发出第二个请求。您可以添加您的Store 的定义吗?你有它的自定义主键吗?另外,在StarRoute 中,尝试将其更改为App.store.find('App.Star', params.star_id)。不确定它是否会有所作为,但请尝试一下
  • 现在你可以看到我的商店定义了。此外,我将 json 中的主键从 _id 更改为 id (因为 mongoid)。我还将出口添加到 stars.js.hdb.hamlbars 中。现在我只有在第一次资源加载时有两个请求,但是如果我之前加载星号,那么每次加载特殊星号时我只有一个请求(按 id)***GET localhost:3000/stars ***

标签: javascript ruby-on-rails ruby routes ember.js


【解决方案1】:

加载 /star/:id 时似乎不想获取所有星星

直接访问/star/1会获取所有星星的原因是star路由嵌套在stars内部

嵌套路由的原因是你的 UI 是嵌套的。这意味着当您查看一颗星星时,在您的 UI 中的某个位置(可能在侧边栏中),您正在显示星星列表。在这种情况下,您需要请求localhost:3000/stars,因为即使您正在查看一颗星星,您也需要显示所有星星。这意味着请求的 ajax 是必需的,因此不是问题。

但是,如果您在查看一颗星星时没有显示所有星星的列表,那么您的路线首先不应该嵌套。在这种情况下,请将您的路线修改为如下所示:

TravelApi.Router.map ->
  @resource 'stars'
  @resource 'star', { path: '/:star_id' }

【讨论】:

  • 好吧,我猜到了。但是如果我已经加载了所有的星星,为什么这个(通过 id)查询会再次加载所有内容而不是从内存中读取?
【解决方案2】:

嵌套资源的工作方式,如果第一个请求返回一个promise(ember数据应该这样做),那么在ajax请求完成之前不会调用嵌套资源/路由模型函数。

按照这个逻辑,应该只有 1 个 ajax 调用。

TravelApi.Star.find() 应该创建一个 ajax 请求来获取所有记录 TravelApi.Star.find(1) 不需要 ajax 请求,因为记录应该在那里。

但是,在您的情况下,star 资源不会等待stars 资源完成 ajax。原因是TravelApi.Star.find() 立即返回结果(存储中的所有可用记录当然是空的),而不是承诺(我认为)。

要解决这个问题,您可以通过在模型中编写以下内容来返回 findQuery 承诺: TravelApi.Star.find({})

这将导致star 资源等待stars 资源完成其ajax 请求。

路线应该是这样的:

TravelApi.StarsRoute = Ember.Route.extend
  model: ->
    TravelApi.Star.find({})

TravelApi.StarRoute = Ember.Route.extend
  model: (params) ->
    TravelApi.Star.find(params.star_id)

【讨论】:

  • 如果我从我的路线中删除 params.star_id,那么我没有任何 id 的请求。所以这行不通。
  • 这是明星路线而不是明星路线。将 params.star_id 保留在 star 路由中。
  • 好的,我试过了,但没有任何效果。正如我在上面的评论中描述的那样。
  • 在我看来,我们都在尝试解决不同的问题。我的建议可以让您避免 localhost:3000/stars/1 请求。如果这是您要避免的,那么我的解决方案应该有效。但在我看来,您试图避免 localhost:3000/stars 请求,对吗?
  • 是的,检查我的第二个答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-14
  • 2014-08-15
  • 2016-04-05
相关资源
最近更新 更多