希望你能帮助我! :)
我的问题是我有一条看起来像这样的路线,我期望填充一个项目列表......即“只有标记的那些,请”,但它没有:
App.TaggedItemsListRoute = App.ItemsRoute.extend({
model: function() {
var store = this.get("store");
var storePromise = store.find("item", { has_tags: true });
var filtered = store.filter("item", function(item) {
return item.get("hasTags");
});
return storePromise.then(function(response) {
return filtered;
});
}
});
现在......只是普通不起作用,因为“hasTags”返回false,因为它依赖于“tags”,它返回一个暂时为空的ManyArray,因为它还没有解决(参见下面的模型)。这对我来说似乎很糟糕。它说“嘿,我没有在我身上!”但我想要它说的是“请稍后重新计算我”,过滤器正在寻找一个布尔值,但我想传递的是“嘿,不要解决过滤器,直到所有的标签都已解决”或至少重新计算它传递的ManyArray。
如果我只是将一个promise作为过滤器的返回值传回,那么它有点可行......
return item.get(“tags”)。then(function(tags){return item.get(“hasTags”);});
除了它实际上没有,beacuse过滤器正在获得Promise,但它显然不知道promises,因此当它在寻找一个布尔值时,它会得到一个它评估为true的promise,然后它几乎显示所有的列表中的项目。这不是一个问题,直到我去一个不同的路线,例如,它上面的所有物品,然后回来......而BAM它有所有物品......嗯....
以下是我暂时“绕过”它的方式......即它仍然是马车,但我可以忍受它......
App.TaggedItemsListRoute = App.ItemsRoute.extend({
model: function() {
var store = this.get("store");
var storePromise = store.find("item", { has_tags: true });
var filtered = store.filter("item", function(item) {
var tags = item.get("tags");
if tags.get("isFulfilled") {
return item.get("hasTags");
} else {
return tags.then(function() {
return item.get("hasTags");
});
}
});
return storePromise.then(function(response) {
return filtered;
});
}
});
我认为在这个阶段真正解决这个问题的唯一方法就是使用RSVP.all ...任何想法?
实际上我现在尝试过的一件事就是使用setupController进行过滤。唯一的麻烦就是所有项目都会被加载到列表中,然后在大约1秒钟之后在视觉上“跳回”到过滤状态。痛苦!
模型
我的Ember应用程序(Ember 1.5.1)有两个型号(Ember Data beta7):项目和标签。物品有很多标签。
App.Item = DS.Model.extend({
tags: DS.hasMany("tag", inverse: "item", async: true),
hasTags: function() {
return !Em.isEmpty(this.get("tags"));
}.property("tags")
});
App.Tag = DS.Model.extend(
item: DS.belongsTo("item", inverse: "tags"),
hasItem: function() {
return !Em.isEmpty(this.get("item"))
}.property("item")
);
如果我将模型更改为以下内容,当我转到上面的路线时,它确实会在日志中打印一些内容,因此 履行承诺。
App.Item = DS.Model.extend({
tags: DS.hasMany("tag", inverse: "item", async: true),
hasTags: function() {
this.get("tags").then(function(tags) {
console.log("The tags are loding if this is printed");
});
return !Em.isEmpty(this.get("tags"));
}.property("tags")
});
这是来自Ember Data hasMany async observed property "simple" issue的分拆问题,因为我没有真正解释我的问题,实际上是在问错误的问题。我原本以为我可以修改我的模型“hasTags”属性,以便在我的路线上下文中正确行为,但我现在认为这不会正常工作......
答案 0 :(得分:1)
这似乎是RSVP.all
非常好的候选人。顺便说一句,如果你想要一个关于RSVP的破坏,我几个星期前就发表了一篇关于它的讨论(不要过多关注它,披萨来了一半,我饿了,http://www.youtube.com/watch?v=8WXgm4_V85E)。无论如何,在执行之前,过滤器显然取决于标记集合承诺的解析。因此,在执行过滤器之前等待那些解决方案是合适的。
App.TaggedItemsListRoute = App.ItemsRoute.extend({
model: function() {
var store = this.get("store");
return store.find("item", { has_tags: true }).then(function(items){
var tagPromises = items.getEach('tags');
return Ember.RSVP.all(tagPromises).then(function(tagCollections){
// at this point all tags have been received
// build your filter, and resolve that
return store.filter("item", function(item) {
return item.get("hasTags");
});
});
});
}
});
http://emberjs.jsbin.com/OxIDiVU/454/edit
另外,如果你觉得你想让这个钩子立即解决,然后神奇地填充,你可以作弊并返回一个数组,然后在结果从服务器返回后填充数组,允许你的应用程序似乎它的反应非常迅速(通过在页面上绘制一些东西,然后在结果涌入时神奇地填充)。
App.TaggedItemsListRoute = App.ItemsRoute.extend({
model: function() {
var store = this.get("store"),
quickResults = [];
store.find("item", { has_tags: true }).then(function(items){
var tagPromises = items.getEach('tags');
return Ember.RSVP.all(tagPromises).then(function(tagCollections){
// at this point all tags have been received
// build your filter, and resolve that
return store.filter("item", function(item) {
return item.get("hasTags");
});
});
}).then(function(filterResults){
filterResults.forEach(function(item){
quickResults.pushObject(item);
});
});
return quickResults;
}
});