我使用ember.js和localstorage-adapter
这是一个带有问题的JSbin:http://jsbin.com/lejizo/9/edit?html,console,output
拥有这些模型:
/* Models */
App.List = DS.Model.extend({
name: DS.attr('string'),
// DOES NOT WORK:: items: DS.hasMany('item')
items: DS.hasMany('item', {async: true})
});
App.Item = DS.Model.extend({
name: DS.attr('string'),
list: DS.belongsTo('list')
});
如果您不使hasMany
异步,则Ember数据会引发错误。顺便说一句,数据在localstoarge
。我把它初始化为:
var FIXTURES = {
'list': {
records: {
'1': {
id: '1',
name: 'The List',
items: ['1','2']
},
'2': {
id: '2',
name: 'The Second List',
items: ['1','3']
}
}
},
'item': {
records: {
'1': {
id: '1',
name: 'item 1',
list: '1' },
'2': {
id: '2',
name: 'item 2',
list: '1'
},
'3': {
id: '3',
name: 'item 3',
list: '1'
}
}
}
}
localStorage.setItem('DS.LSAdapter', JSON.stringify(FIXTURES));
无论如何,让items: DS.hasMany('item', {async: true})
使应用程序顺利运行。
问题在于,如果我尝试从Controller访问items
它们不是对象,它们只是一个承诺!这迫使我们使用以下方法:
list.get('items').then(function(items) { // must use then
items.forEach(function(item){
console.log(item.get('id'));
});
});
这对我来说似乎很尴尬,要始终注意hasMany
关系并小心你如何使用它们,而不是仅仅使用相关对象来处理任何其他关系..
这是正常还是我错过了什么? 有没有解决方法来不定义它们async:true,因为所有数据都已经在localstorage中了? 我们是否应始终将控制器用于所有相关实体作为最佳实践?
答案 0 :(得分:2)
这对我来说似乎很尴尬,要始终注意hasMany关系并小心你如何使用它们,而不是仅仅使用相关对象和任何其他关系..
那会很尴尬,这就是你不必这样做的原因。 ;)在大多数情况下,Ember会自动监视属性更新并相应地传播它们。那是什么意思?这意味着你不应该担心价值是一种承诺; 使用它,好像它不是。
简而言之,Ember使用一种特殊的承诺来监视房产更新。所以,让我们说你有以下模板:
{{#each item in model.items}}
{{item.name}}
{{/each}}
如果model.items
是异步hasMany
关系,Ember仍然会做正确的事情。模板首次渲染时,将没有数据。 你的each
循环不会产生任何效果。但是Ember会看model.items
属性进行更新。当它有更新时(例如,当promise解析时),Ember将再次运行模板。这一次,数据将在那里,它将完全按照您的预期工作。
属性也是如此:
function() {
return this.get('model.items').filter(function(item) {
return !!item;
});
}.property('model.items.@each')
此属性将在第一次运行时返回一个空数组。但是,当承诺结算时,Ember将再次运行该属性并产生您想要的结果。
在幕后有很多事情发生,但在你遇到一些更复杂的用例之前,你通常不必担心这一点。如果您想了解更多信息,建议您查看以下资源:
编辑:如果你想修改关系,例如,添加一个新项目,做这样的事情:
actions: {
addPost: function(post) {
this.get('model.posts').then(function(posts) {
posts.addObject(post);
});
}
}