让我们说
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')的重新加载,即发送GET请求,例如post / 42 / comments。
有没有解决方案?
答案 0 :(得分: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/
答案 1 :(得分:7)
感谢@igorT,这是实现的。 https://github.com/emberjs/data/pull/2297
现在ManyArray有一个reload()方法,如果尚未加载关系,你甚至可以调用它。
您可以通过阅读tests
来查看一些用例答案 2 :(得分: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
});
}
});
我承认它并不是非常漂亮,但它是我提出的最佳解决方案,直到重新加载直接构建到关联中。
答案 3 :(得分:1)
我遇到了同样的问题而且我被骗了找到一个“解决方案”
我创建了一个组件“CommentLoader”。该组件采用一个参数(post_id)和 在“插入”(willInsertElement)之前,我将所有注释都渲染并渲染它们。它有效,但......我并不为此感到骄傲:(
答案 4 :(得分:1)
使用 ember-data-1.0.0-beta.10 我正在使用以下型号扩展程序。
只需调用model.reloadRelationship(name)
,其中name是表示关系的model属性的名称。
这适用于普通和链接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来检索记录,否则它将调用reload)。
答案 5 :(得分: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