希望你能帮助我! :)
我的问题是,我有一个看起来像这样的路线,我希望填充一个项目列表...即“请仅填充标记的项目”,但事实并非如此:
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,因为它尚未解析(请参见下面的模型)。这对我来说似乎很糟糕。它在说:“嘿,我什么都没有!”但我想要它说的是“请稍后重新计算我”并且过滤器正在寻找一个 bool 值,但我想要传递的是“嘿,在所有 hasTags 都解析之前不要解析过滤器”或者至少重新计算它传递的ManyArray。
如果我只是传回一个 promise 作为过滤器的返回值,那么它就可以工作......
return item.get("tags").then(function(tags){ return item.get("hasTags"); });
除了它实际上不是,因为过滤器得到了一个 Promise,但显然它不知道 Promise,所以当它寻找一个 bool 值时,它得到一个它评估为 true 的 Promise,然后它几乎显示了所有列表中的项目。这不是问题,直到我去不同的路线寻找元素,比如说,上面有所有元素,然后回来......然后砰的一声,里面有所有元素......嗯......
以下是我暂时“解决”它的方法...即它仍然有问题,但我可以忍受它...
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")
);
如果我将模型更改为以下内容,当我转到上面的路线时,它实际上会在日志中打印一些内容,因此它履行了 promise 。
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”属性,以便在我的路线上下文中正确运行,但我现在认为这不会正常工作......
最佳答案
这似乎是 RSVP.all
的完美候选者。顺便说一句,如果您想了解 RSVP 的概要,几周前我曾就此做过一次演讲(也不要太在意,披萨吃到一半,我饿了,http://www.youtube.com/watch?v=8WXgm4_V85E)。无论如何,您的过滤器显然取决于在执行之前解析的标签集合 promise 。因此,在执行过滤器之前等待这些问题解决是合适的。
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");
});
});
});
}
});
使用类似的颜色想法的示例(我仅在关系有 3 个关联颜色时才显示)
http://emberjs.jsbin.com/OxIDiVU/454/edit
另外,如果您希望这个钩子(Hook)立即解析,并在之后神奇地填充,您可以作弊并返回一个数组,然后在结果从服务器返回后填充该数组,从而允许您的应用程序看起来它的 react super 快(通过在页面上绘制一些东西,然后随着结果涌入而神奇地填充)。
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;
}
});
快速结果示例,立即返回(我仅在关系有 3 个关联颜色时才显示)
关于javascript - 带有 Ember 数据 "filter"的路线模型 Hook 未加载依赖的计算属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23508300/