如果我不需要嵌套模板,如何从Ember应用程序调用嵌套的Rails路由? 我在Rails路由器中有以下路由:
# routes.rb
resources :shops do
resources :shop_languages
end
因此,要获得商店语言列表,应该点击shops/:shop_id/shop_languages
。
这是ShopsLanguagesController:
# controllers/shop_languages_controller.rb
class ShopLanguagesController < ApplicationController
before_action :find_shop
def index
json_response @shop.shop_languages, :ok, include: 'language'
end
private
def find_shop
@shop = Shop.find(params[:shop_id])
end
end
在Ember应用程序中,我的路线定义如下:
# router.js
Router.map(function() {
...
this.route('languages', { path: '/shops/:shop_id/shop_languages'});
});
在Ember application.hbs
模板中,语言链接定义如下
# application.hbs
{{#link-to 'languages' currentUser.user.shop.id class="nav-link"}}
..
{{/link-to}}
在Ember languages.js
路由处理程序中,我正在尝试加载商店语言:
# routes/languages.js
model(params) {
return this.store.query('shop-language', { shop_id: params.shop_id })
}
Ember点击/shop-languages
终点而不是嵌套的shops/:shop_id/shop_languages
。
当然,我已经在Ember方面定义了相应的模型:
# models/shop-language.js
import DS from 'ember-data';
export default DS.Model.extend({
shop: DS.belongsTo('shop'),
language: DS.belongsTo('language'),
modified_by: DS.attr('string')
});
这有什么问题以及如何使其发挥作用?谢谢
答案 0 :(得分:3)
答案简短;对服务器的请求与您的路由结构不匹配,但是基于您的模型和您正在使用的适配器,例如REST与JSON API基于服务器上调用的URL可能不同。
因此,要将/shop/:id/
添加为shop-language
查询的前缀,您必须覆盖适配器的默认行为。
开始为您的模型生成适配器
ember g adapter shop-language
在新的适配器中,您可能必须覆盖2个功能
1)query
(https://github.com/emberjs/data/blob/master/addon/adapters/rest.js#L549)
2)urlForQuery
(https://github.com/emberjs/data/blob/master/addon/-private/adapters/build-url-mixin.js#L188)
另请查看处理所有不同方案的buildURL
(https://github.com/emberjs/data/blob/master/addon/-private/adapters/build-url-mixin.js#L55)。
在1)您可能希望从查询参数中删除shop_id
,这样您就不会得到像/shops/1/shop-languages?shop_id=1
这样的网址
2)您必须根据传递的查询参数将/shops/1
添加到您的网址
答案 1 :(得分:0)
感谢@dguettler,我找到了一个解决方案来实现它。
在灰烬方面
声明语言路由如下:
#router.js
Router.map(function() {
this.route('languages', { path: 'shops/:shopId/languages'});
..
});
修改/创建languages.js
路由处理程序,如下所示:
#routes/languages.js
import Route from '@ember/routing/route';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
export default Route.extend(AuthenticatedRouteMixin, {
model(params) {
return this.store.query('shop-language', { shopId: params.shopId});
}
});
创建/修改shop-language.js
适配器,如下所示:
#adapters/shop-language.js
export default ApplicationAdapter.extend({
urlForQuery (query) {
return this._buildShopUrl(query.shop_id)
},
urlForCreateRecord(modelName, snapshot) {
return this._buildShopUrl(snapshot.belongsTo('shop').id);
},
urlForDeleteRecord(id, modelName, snapshot) {
return this._buildShopUrl(snapshot.id, id);
},
_buildShopUrl(shop_id, id) {
if (id) {
return `shops/${shop_id}/languages/${id}`;
}
return `shops/${shop_id}/languages`;
}
});
添加链接以将商店语言加载到您的模板:
#templates/application.hbs
...
{{#link-to 'languages' currentUser.user.shop.id class="nav-link"}}
...
{{/link-to}}
在languages.hbs
模板中显示商店语言:
#templates/languages.hbs
<ul class="list-group list-group-flush">
{{#each model as |lang|}}
<li class="list-group-item">{{lang.tag}}</li>
{{/each}}
</ul>
在Rails API方面
将shop_languages资源声明为嵌套路由:
#routes.rb
...
resources :shops do
resources :shop_languages, path: '/languages'
end
在ShopLanguagesController
中加载商店语言:
#controllers/shop_languages_controller.rb
class ShopLanguagesController < ApplicationController
before_action :find_shop
def index
json_response @shop.languages, :ok
end
private
def find_shop
@shop = Shop.find(params[:shop_id])
end
end
我有一件事要做 - 从网址中删除?shopId=613
并修复包含一种双重值的params哈希:
Started GET "/shops/613/languages?shopId=613" for 127.0.0.1 at 2018-03-23 10:05:53 +0100
Processing by ShopLanguagesController#index as JSONAPI
Parameters: {"shopId"=>"613", "shop_id"=>"613"}