我有点坚持在emberjs中实现主从 View 。
我的大多数 View 都有一个主 View ,这只是标题列表。然后,用户可以单击这样的标题,然后他/她将获得详细 View 的覆盖图(有点像典型的newsitem页面)。
现在,我注意到,当ember向主 View 询问信息时,它将调用诸如/backend/newsitems
的url。但是这些调用会变得很繁琐,因为后端会返回所有新站点及其所有详细数据的列表。但这感觉不对,因为用户仅查看主 View ,而尚未请求任何详细信息。
有没有办法使 Ember 清楚,主 View 只需要几个属性,并且对详细信息的请求应该获得该特定项目的额外属性?
举例来说,我的模型如下所示:
App.Newsitem = DS.Model.extend({
slug: DS.attr('string'),
type: DS.attr('string'),
title: DS.attr('string'),
summary: DS.attr('string'),
text: DS.attr('string'),
thumb: DS.attr('string'),
date: DS.attr('date'),
mediaitems: DS.hasMany('App.Mediaitem')
});
但是我的主 View 只需要
id
type
title
即可显示标题列表和该标题旁边的图标。然后,当用户请求一个新站点的详细信息时,应获取所有其他属性。
最佳答案
我通过让服务器在有效负载中包含“partial”属性来解决了这个问题。如果只是部分响应,则“部分”将为true;如果是完整响应,则将为false。如果您无法更改服务器API(因此不能在有效负载中包含'partial'属性),我还将提供一种解决方法。
正如其他人所建议的那样,如果当前加载的模型只是部分模型,则在“详细”路线的模型 Hook 中,调用模型的reload()方法:
App.ItemRoute = Ember.Route.extend({
model: function (params) {
return this.store.find('item', params.item_id).then(function (item) {
if (item.get('partial'))
return item.reload();
else
return item;
});
}
});
这解决了部分问题,但是如果用户随后导航到主路由,则Ember Data将用服务器响应替换所有字段,并清除服务器未返回的所有属性值。为了克服这个问题,请像这样重写商店的push方法:
App.ApplicationStore = DS.Store.extend({
push: function (type, data, _partial) {
if (data.partial && this.hasRecordForId(type, data.id))
return this.getById(type, data.id);
else
return this._super(type, data, _partial);
}
});
这样可以确保您的部分有效负载不会覆盖全部有效负载。
这是一个演示的jsbin:http://jsbin.com/bejop/6/edit
如果您不能在响应中包含“部分”属性,则可以应用与上述相同的逻辑,但是要在模型中查找将出现在详细响应中而不是部分响应中的特定属性。然后,当您覆盖push方法时,您可以这样做:
App.Partials = [
{ type: App.Item, propertyName: 'detailed_description' }
];
App.ApplicationStore = DS.Store.extend({
push: function (type, data, _partial) {
var that = this;
var partial = App.Partials.find(function (p) {
return p.type === that.modelFor(type);
});
if (partial && !data[partial.propertyName])
return this.getById(type, data.id);
return this._super(type, data, _partial);
}
});
关于ember.js - 在emberjs中用更详细的数据动态填充模型,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15222739/