12

可以说我们有

Post = DS.Model.extend({
  comments: DS.hasMany({async: true})
})

Comment = DS.Model.extend({
  post: DS.belongsTo()
})

而且我必须使用该links功能,否则我会因为帖子评论过多而收到 414 错误。

自此提交https://github.com/emberjs/data/commit/4d717bff53f8c93bedbe74e7965a4f439882e259

似乎不可能触发 post.get('comments') 的重新加载,即在例如 post/42/comments 上发送 GET 请求。

有什么解决办法吗?

4

6 回答 6

15

更新

就像@sly7_7 在您下面的回答中所说的那样,此功能现在可在 ember-data 中使用。因此,如果您使用的是 1.0.0-beta.11 或更高版本,则不需要此代码

您可以重新打开ManyArray,并创建一个名为 的新方法reloadLinks()。具有以下内容:

var get = Ember.get;

DS.ManyArray.reopen({
    reloadLinks: function() {
        var records = get(this, 'content'),
        store = get(this, 'store'),
        owner = get(this, 'owner'),
        type = get(this, 'type'),
        name = get(this, 'name'),
        resolver = Ember.RSVP.defer();

        var meta = owner.constructor.metaForProperty(name);
        meta.type = type;
        var link = owner._data.links[meta.key];
        store.findHasMany(owner, link, meta, resolver);
    }
});

用法如下:

comments.reloadLinks();

看看那个小提琴http://jsfiddle.net/H6Gqf/

于 2013-11-27T17:03:19.990 回答
7

感谢@igorT,这已实现。https://github.com/emberjs/data/pull/2297

现在 ManyArray 有一个 reload() 方法,如果关系尚未加载,您甚至可以调用该方法。

您可以通过阅读测试来查看一些用例

于 2014-09-19T14:08:02.687 回答
2

重新加载 hasMany 还没有直接内置到 Ember Data 中,但它正在路上。我使用的解决方案需要 Ember Data 1.0b9+canary,其中包括opt-in coalesced finds

第 1 步:选择加入。

我选择了 ApplicationAdapter 级别,但您可能希望在每个模型适配器的基础上进行。这是我所拥有的:

MyApp.ApplicationAdapter = DS.ActiveModelAdapter.extend({
  coalesceFindRequests: true
});

为了让您了解为什么这很重要和很好,我们应用程序的一个页面在此更改之前看到了 50 多个请求。我们现在只看到 11 个。它仍然不是很好,但这是一个非常好的改进!

第 2 步:在协会中重新加载记录

我只是简单地在我的模型上的一个函数中重新加载,如下所示:

MyApp.SomeModel = DS.Model.extend({
  fooMany: DS.hasMany('foo', { async: true }),
  barMany: DS.hasMany('bar', { async: true }),
  bazOne: DS.belongsTo('baz', { async: true }),

  reloadAssociated: function () {
    var foosPromises = this.get('foos').invoke('reload'),
        barsPromises = this.get('bars').invoke('reload'),
        bazPromise = this.get('baz').reload();

    return Em.RSVP.hash({
      foos: foosPromises,
      bars: barsPromises,
      baz: bazPromise
    });
  }
});

我承认它不是非常漂亮,但它是我想出的最好的解决方案,直到重新加载直接内置到关联中。

于 2014-07-30T12:44:24.927 回答
1

我有同样的问题,我作弊找到一个“解决方案”

我创建了一个组件“CommentLoader”。该组件采用一个参数( post_id ),在“插入”(willInsertElement)之前,我对所有评论进行分级并呈现它们。它有效,但......我并不为此感到自豪:(

于 2013-11-27T10:26:07.840 回答
1

使用ember-data-1.0.0-beta.10我正在使用以下模型扩展。

只需调用model.reloadRelationship(name)where name 是表示关系的模型属性的名称。

这适用于普通和链接 belongsTo/hasMany 关系。

DS.Model.reopen({
    reloadRelationship: function(name) {
        var meta = this.constructor.metaForProperty(name),
            link = this._data.links ? this._data.links[meta.key] : null;
        if (!link) {
            if (meta.kind === 'belongsTo') {
                this.get(name).then(function(model) { model.reload(); });
            } else {
                this.get(name).invoke('reload');
            }
        } else {
            meta.type = this.constructor.typeForRelationship(name);
            if (meta.kind === 'belongsTo') {
                this.store.findBelongsTo(this, link, meta);
            } else {
                this.store.findHasMany(this, link, meta);
            }
        }
    }
});

这里唯一缺少的是一些检查,例如,在使用链接重新加载模型时检查模型是否已经重新加载,或者检查属性名称是否存在于当前模型中。

编辑 ember-data-1.0.0-beta.14:

DS.Model.reopen({
    reloadRelationship: function(key) {
        var record = this._relationships[key];
        if (record.relationshipMeta.kind === 'belongsTo') {
            return this.reloadBelongsTo(key);
        } else {
            return this.reloadHasMany(key);
        }
    },
    reloadHasMany: function(key) {
        var record = this._relationships[key];
        return record.reload();
    },
    reloadBelongsTo: function(key) {
        var record = this._relationships[key];
        if (record.link) {
            return record.fetchLink();
        } else {
            record = this.store.getById(record.relationshipMeta.type, this._data[key]);
            return record.get('isEmpty') ? this.get(key) : record.reload();
        }
    }
});

HasMany 关系将回退到本机重新加载方法。

对于 BelongsTo 关系,它会首先检查记录是否需要重新加载(如果之前没有加载,它只会调用 get 来检索记录,否则会调用重新加载)。

于 2014-09-18T21:35:29.663 回答
0

另一种选择是向模型添加方法。也应该适用于 hasMany:

search: DS.belongsTo('search', {async: true})

updateSearch: ->
  resolver = Ember.RSVP.defer()
  resolver.resolve = =>
    # do something after promise resolves
  relationship = @constructor.metaForProperty('search')
  link = @_data.links[relationship.key]
  @store.findBelongsTo this, link, relationship, resolver
于 2013-12-13T06:37:03.793 回答