按相关模型过滤模型(hasMany)

时间:2013-12-24 11:31:43

标签: ember.js ember-data

我有一个相关tags的产品列表。我想过滤列表以仅显示具有指定标记的产品:

App.Product = DS.Model.extend({
    tags: DS.hasMany('Tag', { async: true }),
    name: DS.attr( 'string' )
});

App.Tag = DS.Model.extend({
    name: DS.attr('string')
});

App.ProductsTaggedRoute = Ember.Route.extend({
    model: function(params) {
        var store = this.store;

        return store.find('product').then(function() {
            store.filter('product', function(product, index, enumerable) {
                var match = false;

                product.get('tags').then(function(tags) {
                    tags.forEach(function(tag) {
                        if(tag.get('name') === 'Tag 1') {
                            console.log(product.get('name') + ' true');
                            match = true;
                        } else {
                            console.log(product.get('name') + ' false', tag.get('name'));
                        }
                    });
                });

                return match;
            });
        });
    }
});

App.Product.FIXTURES = [
    { id: 1, tags: [1,2,3], name: "test 1" },
    { id: 2, tags: [3], name: "test 2" },
    { id: 3, tags: [2,1], name: "test 3" },
    { id: 4, tags: [], name: "test 4" }
];

App.Tag.FIXTURES = [
    { id: 1, name: "Tag 1" },
    { id: 2, name: "Tag 2" },
    { id: 3, name: "Tag 3" },
    { id: 4, name: "Tag 4" }
];

输出结果为:

test 2 false undefined
test 3 false undefined
test 3 false undefined
test 1 true
test 1 false Tag 2
test 1 false Tag 3 

我不明白为什么前三个未定义?此外,我没有在模板中获得任何输出,因此看起来过滤器功能不正确:

{{#each controller}}
    {{ name }}
{{/each}}

1 个答案:

答案 0 :(得分:2)

在使用过滤器之前,您需要确保记录已解决。这是承诺的完美用例。你返回一个承诺,并控制解决的问题和时间。

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

model: function(params) {
    var store = this.store;

    return new Em.RSVP.Promise(function(resolve){
      //find products
      store.find('product').then(function(products) {
        // get all the tag promises
        var promiseArr = products.getEach('tags');
        //wait on them
        Em.RSVP.all(promiseArr).then(function() {

          var filter = store.filter('product', function(product, index, enumerable)   {
            var match = false;

            product.get('tags').forEach(function(tag) {
              if(tag.get('name') === 'Tag 1') {
                console.log(product.get('name') + ' true');
                match = true;
              } else {
                console.log(product.get('name') + ' false', tag.get('name'));
              }
            });

            return match;
          });  //filter

          resolve(filter);
       });  // RSVP All  
    });   //find
  });   // promise

 }