EmberJS 求助 Ember.js 同一 model 不同 API 的方案

guxiaobai · March 19, 2016 · Last by nightire replied at March 19, 2016 · 6834 hits

server api

  • example.com/api/v1/contacts
  • example.com/api/v1/admin/contacts

ember

app/router.js

this.route('contacts', function() {});

this.route('admin', function() {
    this.route('contacts', function() {});
});

app/adapters/application.js

import ActiveModelAdapter from 'active-model-adapter';

export default ActiveModelAdapter.extend({
  namespace: 'api/v1'
});

example.com:4200/contacts --> example.com/api/v1/contacts (成功) example.com:4200/admin/contacts --> example.com/api/v1/admin/contacts (失败)

有一个思路是 重写 pathForType,

$E.currentPath
"admin.contacts.index"

基于这个思路不知道如何在 app/adapters/application.js 获取到这个值。

希望有关方面的经验给予参考

@nightire 能否给予帮助

#1 楼 @guxiaobai

首先,我不觉得这俩是同一个 Model,我可以想出这种思路在很多场景下会引发的问题。我觉得你应该问问你自己:/contacts/admin/contacts 能确保始终是 Same Model 吗?

在我看来,八成这两者会出现差异的,即使你现在觉得看不出,也不代表这样做就一定很安全。若是我的话,我会做一个 AdminContact Model,它可以继承自 Contact Model,这没有问题。

客户端的 Model 和服务端的 Model 是不一样的,如果简单的说服务端的 Model 是对数据库的一种对象映射,那么客户端的 Model 就是对 API 的一种映射。如果一个 Model 可以同时适应 /contacts/admin/contacts,那我看不出要有两个 API endpoint 的必要。

可是呢,如果你非要这么做那也不是没有办法,比如说你关心的 pathForType,实际上你已经看到了它是 DS.BuildURLMixin 里的一个成员属性,那么你只需要在扩展 ActiveModelAdapter 的时候用上这个 Mixin 就可以获得它了啊:

export default ActiveModelAdapter.extend(BuildURLMixin, {
  namespace: 'api/v1',

  anyMethod() {
    console.log(this.pathType); // here is what you want
  }
});

可是我不觉得你在这条路上会找到解决问题的办法,我问你一个问题:谁负责在不同的路由去请求不同的 API endpoint?

因为你只有一个 Model,你也只能用 store.findAll('contact') 这一个方法来获取所有 contacts(举例),在不同的地方调用的结果却是一样的,你如何区分哪儿是哪儿?

即使我告诉你,store 最终是通过 adapter 里对应的方法去发出请求,OK,你决定去重写 DS.Adapter.findAll 方法,可是你还是无法判断一个 call 进来到底是要请求 /contacts 还是 /admin/contacts,因为 store.findAll('contact') 这个方法是没有变的。

你可以做许多的 hackin 来绕过这个机制,比如说通过 naming resolver 来动态查找不同的 Adapter 之类的,但是这都不是标准的 Ember Data 的逻辑,你说不准走远了以后会遇到什么样的坑。

所以还是我最早的结论,你这个设计有问题。如果有两个 endpoint,那么就应该有两个 client model。

BTW,有一种非常规的方法,就是在 Model 里定义 Static Method,“人为”的发请求拿数据然后再 pushPayload——这是可行的,但是 payload 的后续控制需要你亲力亲为,如果你对 Ember Data 的各种机制不是很通的话,不建议这么玩儿。

You need to Sign in before reply, if you don't have an account, please Sign up first.