如何编写一个可以获得块的findMany?

时间:2014-06-01 18:35:15

标签: ember.js ember-data

Ember 1.5.1 Ember-Data 1.0 beta 7

我已尝试修改DS.ActiveModelAdapter的findMany,因此它会获得40块...这是因为我无法使用链接功能生成400个错误,因为它创建的URL中有太多的ID。

我尝试使用此适配器,但我不断收到如下所示的错误消息:

    Error: Assertion Failed: Error: no model was found for 'super'

这是我的适配器:

    App.ApplicationAdapter = DS.ActiveModelAdapter.extend({
        findMany: function(store, type, ids) {
          self = this;
          return new Ember.RSVP.Promise(function(resolve, reject) {
            var idsPerRequest = 40;
            var totalIdsLength = ids.length;
            var numberOfBins = Math.ceil( totalIdsLength / idsPerRequest ); // number per bin
            var bins = [];
            ids.forEach( function(someId, index) {
              var thisBinIndex = index % numberOfBins;
              var thisBin = Ember.A( bins[thisBinIndex] );
              thisBin.pushObject(someId);
              bins[thisBinIndex] = thisBin;
            });

            var requestPromises = bins.map(function(binOfIds) {
              return self.ajax(self.buildURL(type.typeKey), 'GET', { data: { ids: binOfIds } });
            });

            Ember.RSVP.all(requestPromises).then(function(resolvedBinRequests) {
              var resolvedObjects = Em.A([]);
              resolvedBinRequests.forEach(function(resolvedBin) {
                resolvedObjects.addObjects(resolvedBin);
              });
              resolve(resolvedObjects);
            }, function(error) {
              reject(error);
            });
          });
        }
    });

任何人都可以帮我解决这个问题吗?我真的很感激。我只是遗漏了一些明显的东西,或者我可能做了些傻事?

提前致谢!

[编辑]好的,我已经进一步了解了它为什么不起作用,而这是因为回复的响应是对JSON有效载荷的承诺,但我正在做的是将这些的多个加入一个数组并返回......显然不会是正确的...但我需要做的是合并返回的对象内的数组一,我认为(在概念上)......我不确定如何实际做到这一点,尽管......我已经尝试了各种各样的事情,但它们似乎都没有奏效...... :(

3 个答案:

答案 0 :(得分:0)

我不确定你对后端有多少控制权,但这似乎是使用links而不是返回所有ID的完美用例。

App.Foo = DS.Model.extend({
  bars: DS.hasMany('bar', {async:true})
});


App.Bar = DS.Model.extend({
  name: DS.attr()
});

然后当你查询foo时,你的json返回一个链接而不是一个id列表

{
  foo: {
    id:1,
    links: {
      bars: '/foo/1/bars'  // or anything, you could put /bars?start=1&end=9000
    }
  }
} 

以下是1000个关系记录命中简单端点的示例:

http://emberjs.jsbin.com/OxIDiVU/579/edit

答案 1 :(得分:0)

经过一些反馈后,我更新了此响应,尝试在序列化器中提取响应有效负载,而不是尝试模拟适配器中存储的逻辑。 http://emberjs.jsbin.com/wegiy/60/edit

App.ApplicationAdapter = DS.ActiveModelAdapter.extend({
  findMany: function(store, type, ids) {
    // build an array of promises, then resolve using Ember.RSVP.all
    var idsPerRequest = 40;
    var totalIdsLength = ids.length;
    var numberOfBins = Math.ceil( totalIdsLength / idsPerRequest ); // number per bin
    var bins = [];
    ids.forEach( function(someId, index) {
      var thisBinIndex = index % numberOfBins;
      var thisBin = Ember.A( bins[thisBinIndex] );
      thisBin.pushObject(someId);
      bins[thisBinIndex] = thisBin;
    });

    var requestPromises = bins.map(function(binOfIds) {
      return self.ajax(self.buildURL(type.typeKey), 'GET', { data: { ids: binOfIds } });
    });

    return Ember.RSVP.all(requestPromises);
  }
});

App.ApplicationSerializer = DS.ActiveModelSerializer.extend({
  extractFindMany: function(store, type, responsePayloads) {
    // responsePayloads is the resolved value from the Ember.RSVP.all(requestPromises) promise

    var serializer = this;
    var extractedResponses = responsePayloads.map(function(payload) {
      return serializer.extractArray(store, type, payload);
    });
    // extractedResponses is an array of arrays. We need to flatten it into 1 array.
    return [].concat.apply([], extractedResponses);
  }
});

答案 2 :(得分:0)

好的,所以我终于找到了如何使这项工作。

我将在此分享我的答案以供将来的后代使用; - )

有趣的是,所需的响应必须是一个承诺,它必须包含一个直接的JS对象,所以我" munged"所有响应到一个JS对象并手动构建复数camelized类型键...我不知道如何做到这一点。所以......对不起,这太酷了,但这确实有效,让我现在修复我的应用程序,直到"链接"功能再次正常工作。

App.ApplicationAdapter = DS.ActiveModelAdapter.extend({
    findMany: function(store, type, ids) {
      self = this;
      return new Ember.RSVP.Promise(function(resolve, reject) {
        var idsPerRequest = 40;
        var totalIdsLength = ids.length;
        var numberOfBins = Math.ceil( totalIdsLength / idsPerRequest ); // number per bin
        var bins = [];
        ids.forEach( function(someId, index) {
          var thisBinIndex = index % numberOfBins;
          var thisBin = Ember.A( bins[thisBinIndex] );
          thisBin.pushObject(someId);
          bins[thisBinIndex] = thisBin;
        });

        // build an array of promises, then resolve using Ember.RSVP.all
        var requestPromises = bins.map(function(binOfIds) {
          return self.ajax(self.buildURL(type.typeKey), 'GET', { data: { ids: binOfIds } });
        });

      // build the required return object, which is a promise containing a plain JS object
      // note this can't be an Ember object
        Ember.RSVP.all(requestPromises).then(function(resolvedBinRequests) {
        var pluralizedDecamelizedTypeKey = type.typeKey.decamelize().pluralize();
        var resolvedObjects = Em.A([]);
        var returnObject = {};
        returnObject[pluralizedDecamelizedTypeKey] = resolvedObjects;
          resolvedBinRequests.forEach(function(resolvedBin) {
          var theArray = resolvedBin[pluralizedDecamelizedTypeKey];
            resolvedObjects.addObjects(theArray);
          });
        var responsePromise = Ember.RSVP.Promise.cast(returnObject);
          resolve(responsePromise);
        }, function(error) {
          reject(error);
        });
      });
    }
});