Route的模型挂钩与Ember数据“过滤器”不加载相关的计算属性

时间:2014-05-07 03:40:46

标签: javascript ember.js ember-data

希望你能帮助我! :)

我的问题是我有一条看起来像这样的路线,我期望填充一个项目列表......即“只有标记的那些,请”,但它没有:

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”属性,以便在我的路线上下文中正确行为,但我现在认为这不会正常工作......

1 个答案:

答案 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");
             });
         });
    });
  }
});

使用与颜色类似的想法的示例(如果关系具有3种关联颜色,我仅显示它)

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;
  }
});

快速结果示例,立即返回(如果关系有3种关联颜色,我只显示它)

http://emberjs.jsbin.com/OxIDiVU/455/edit