Ember js使用嵌套资源URL处理API端点

时间:2013-05-05 23:49:16

标签: ember.js ember-data

我的API的一部分设置如下:

/v1/place/:place_uuid - 检索地点

/v1/place/:place_uuid/cart - 检索与该地点相关联的购物车对象

我的路线设置正确(见下文),但Ember提出的API请求与我自己的不一致。

App.Router.map(function() {
    this.resource('place', { path: '/:place_uuid' }, function() {
        this.resource('category', { path: '/:category_uuid' }, function() {
            this.resource('product', { path: '/:product_uuid' });
        });
        this.resource('cart', { path: '/cart' });
    });
});

当我在浏览器中加载/:place_uuid时,我看到/v1/place/:place_uuid的API请求是正确的。路线使用返回的对象进行渲染。

当我在浏览器中加载/:place_uuid/cart时,我看到与上面相同的内容,但也是/v1/carts的第二个API请求。除了/v1/carts网址外,这一切都很好。我需要它/v1/place/:place_uuid/cart

我尝试将buildURL与Cart模型的自定义适配器一起使用..但没有运气。我无法在下面任何地方访问place_uuid,因此我无法将其注入。

cartAdapter = App.Adapter.extend({
  buildURL: function(record, suffix) {
    console.log(record); // just a string. 
    var url = [this.url];
    url.push('places');
    url.push(place_uuid); // if only I had access to place_uuid I could inject it here
    url.push('cart');
    return url.join("/");
  }
});
App.Store.registerAdapter('App.Cart', cartAdapter);

如果我可以使用我的原始API端点,那将是很好的,我想另一个选择是将端点更改为/v1/carts?place_uuid=:place_uuid(Ember似乎更喜欢,但是因为我不工作而有点棘手在后端)。

感谢任何建议。

3 个答案:

答案 0 :(得分:4)

Ember尚不支持嵌套的REST URLS /资源。您可以监控open issue for this functionality

答案 1 :(得分:1)

这是我的方法:

像这样修补您的DS.Store:

import DS from 'ember-data';

export default {
  name: 'patches',

  initialize: function() {
      // +++ Nested routes +
      DS.Store.reopen({
          __nestedAdapter__: null,

          nest: function(type) {
              this.set('__nestedType__', this.adapterFor(type));
              return this;
          },

          withResources: function(resources) {
              this.get('__nestedType__').set('nestedResources', resources);
              this.set('__nestedType__', null);
              return this;
          }
      });
  }
};

将此添加到您的适配器:

import DS from 'ember-data';

export default DS.RESTAdapter.extend({

    nestedResources: {},

    buildURL: function(type, id, record) {
        var resources = this.nestedResources;
        var parts = [this.get('host')];

        for(var key in resources) {
            if (resources.hasOwnProperty(key)) {
                var resource = resources[key];
                parts.push(
                    Ember.Inflector.inflector.pluralize(key)
                );
                if(isNaN(resource)) {
                    parts.push(resource.get('id'));
                } else {
                    parts.push(resource)
                }
            }
        }

        parts.push(
            Ember.Inflector.inflector.pluralize(type),
            id
        );

        this.set('nestedResources', {});
        console.log(parts.join('/'));
        return parts.join('/');
    }

});

使用富有表现力的语法:

that.store.nest('user').withResources({comment: comment}).find('user')

这可以肯定缩短,但我喜欢它。

答案 2 :(得分:1)

无耻插头:)

我写了https://github.com/amiel/ember-data-url-templates来帮助解决这种情况。它适用于较新版本的ember-data。有了它,你可以这样做:

App.CartAdapter = App.ApplicationAdapter.extend({
  queryUrlTemplate: "/v1/place/{placeId}/cart",

  urlSegments: {
    placeId(type, id, snapshot, query) {
      return query.placeId;
    }
  }
});


// in the route
this.store.query('cart', { placeId: placeId });

我希望有帮助:)