要学习Ember.js,我开始编写一个小书签应用程序。我现在正在努力解决与错误数据处理相关的问题。
解释申请
问题
链接数据不是写入数据存储的。因此,覆盖了由于选择更改而导致的链接模型的本地更新。此外,稍后实现真正的持久性也行不通。
缩小问题范围
在IndexRoute中我初始化模型:
model: function(params) {
return {
labels: this.get("store").find("label"),
// TODO: this is probably wrong.
links: Ember.A()
};
}
一方面,我从数据存储中获取标签数据。另一方面,我使用空的ember数组初始化链接数据。
在我看来,这是故障的根源,但我不知道如何正确实施。 我试图用存储适配器的虚假引用替换它:
this.get("store").find("label").filter("_")
这既不对,也不正常。然后它继续到我无法使用存储适配器更新记录的程度:
// TODO: this is probably wrong.
this.get("links").addObject({
name: linkName,
url: linkUrl,
labels: this.selectedLabels
});
/*store.push("link", {
name: newLink,
url: linkUrl,
labels: this.selectedLabels
});*/
等等。
Jsbin:http://jsbin.com/ucanam/1751/edit
如何正确存储链接数据,以便更改控制器的本地数据不会破坏应用程序?
修改
我想我在你的建议中发现了我的概念错误。这是否意味着我总是要处理本地副本?
var link = this.get("model");
link.deleteRecord();
link.save().then(function(link) {
var indexController = this.get('controllers.index');
indexController.get("links").removeObject(link);
});
在您的示例中,您使用了将对象添加到控制器的承诺。在此代码示例中,承诺永远不会实现 - 因此它只能在没有。
的情况下工作同样在LabelController
中,remove方法也应删除相关链接。如果我在forEach循环中使用deleteRecord
它只删除一个标签然后以某种方式使循环退出。这是故意还是我犯了错误?
我已经更新了你的JsBin http://jsbin.com/ucanam/1987/edit
答案 0 :(得分:3)
我修改了你的JSbin http://jsbin.com/ucanam/1975/
如果您想要保留记录,则必须使用 createRecord()在商店中创建它们,然后保存()。新的newLink功能
newLink: function() {
var store = this.get("store"),
linkName = this.get("linkName"),
linkUrl = this.get("linkUrl"),
links = this.get("links"),
selectedLabels = this.get('selectedLabels');
if(selectedLabels.get('length') > 0) {
if(linkName.length > 0 && linkUrl.length > 0) {
var newLink = store.createRecord('link',
{
name: linkName,
url: linkUrl
});
selectedLabels.forEach(function(label){
newLink.get('labels').addObject(label);
});
newLink.save().then(function(link){
links.addObject(link);
});
this.set("linkName", "");
this.set("linkUrl", "");
}
} else {
alert("You have to select a label!");
}
},
对于删除记录,使用forEach 存在问题,因为查找商店的结果是实时数组。您可以在GitHub https://github.com/emberjs/data/issues/772中看到此讨论。 所以你的删除标签功能应该是(注意使用 toArray()来制作实时数组的静态副本)
remove: function() {
var indexController = this.get('controllers.index'),
label = this.get('model'),
linksPromise = this.get('store').find('link');
linksPromise.then(function(links){
links.toArray().forEach(function(link){
var linkLabels = link.get('labels'),
linkLabelsIds = linkLabels.mapProperty('id');
if(linkLabelsIds.contains(label.get("id"))) {
if(linkLabelsIds.get("length") == 1) {
console.log("delete link: "+link.get("name"));
indexController.get("links").removeObject(link);
link.deleteRecord();
link.save();
}
}
});
label.deleteRecord();
label.save();
});
}
最后注意事项,不要忘记在删除记录后对记录进行保存(),jsBin在这里:http://jsbin.com/ucanam/1989/
答案 1 :(得分:1)
您是否定义了模型?
App.Label = DS.Model.extend({
title: DS.attr('string'),
links: DS.hasMany('link')
});
App.Link = DS.Model.extend({
name: DS.attr('string'),
url: DS.attr('string'),
labels: DS.hasMany('label')
});
App.IndexRoute = Ember.Route.extend({
model: function() {
this.store.find('label')
}
});
App.LabelController = Ember.ObjectController.extend({
actions:
<!-- functions here -->
});
<script type='text/handlebars' data-template-name="index">
{{#each label in model itemController='label'}}
{{label.title}}
{{#each link in label.links}}
{{link.title}}
{{/each}}
{{/each}}
</script>