javascript - Ember Controller 计算属性(对象类型)更新不起作用

标签 javascript ember.js

我正在尝试将排序属性(sortPropertiessortAscending)与数据列表上的过滤器结合起来。

我有一个 ArrayController 和两个操作,一个用于排序,一个用于过滤器。过滤器操作在 filters 对象上设置属性,但依赖于 filters 的属性不会重新计算。

相关 Controller 代码:

App.PostsController = Ember.ArrayController.extend({
  filters: Ember.Object.create({}),
  filteredContent: function () {
    var ret = this.get('arrangedContent');
    Object.keys(this.filters).forEach(function (name) {
      ret = ret.filter(this.filters.get(name));
    }, this);
    return ret;
  // I expect this to cause `filteredContent` to depend on `filters` property
  }.property('arrangedContent', 'filters'),

  actions: {
    sort: function(property, isSorted) {
      this.set('sortProperties', [property]);
      if (isSorted) {
        this.toggleProperty('sortAscending');
      } else {
        this.set('sortAscending', true); 
      }
    },
    filter: function (property, value) {
      var filters = this.get('filters');
      switch (property) {
        case 'id':
          // I expect that call to `set` would trigger `filteredContent` property update
          filters.get('id') || filters.set('id', function (post) {
            return post.get('id') < value;
          });
          break;
        case 'title':
          filters.get('title') || filters.set('title', function (post) {
            return post.get('title').indexOf(value) !== -1;
          });
          break;
      }

    }
  }
});

所以,我的问题是为什么 filters.set() 不会导致 filteredContent 函数运行?

所有代码都在这里 –  http://jsbin.com/silun/7/edit?html,js,output

最佳答案

您正在更新 filters 对象的属性,因此您需要观察正在更改的特定对象属性。

您可以通过显式列出要依赖的属性来做到这一点:

filteredContent: function () {
  //...
}.property('arrangedContent', 'filters.id', 'filters.title'),

或者使用名为 property brace expansion 的速记符号.

filteredContent: function () {
  //...
}.property('arrangedContent', 'filters.{id,title}'),

更新了 JSBin:http://jsbin.com/nuyegowede/1/edit

更新

新的 JSBin ,其中 filters 作为数组:http://jsbin.com/yayihazoza/1/edit

如果您想要无限的过滤器属性而不更新计算属性,您可以使用配置过滤器作为数组而不是对象。这使您可以使用 Ember 的数组观察器功能( @each 在数组更改时自动更新过滤。

filters 现在是一个过滤器对象数组,其形式如下:

   {
     name: 'name-of-filter',
     filter: function(){
       // implementation of filter here
     }
   }

更新filter以将过滤器对象推送到filters数组中:

filter: function (property, value) {
      var filters = this.get('filters');
      console.log("filter", property, value);
      
      switch (property) {
        case 'id':
          if (filters.findBy('name', 'id') === undefined) {
            filters.pushObject({
              name: 'id',
              filter: function (post) {
                return (post.get('id') < value);
              }
            });
          }
          break;
        case 'title':
          if (filters.findBy('name', 'title') === undefined) {
            filters.pushObject({
              name: 'title',
              filter: function (post) {
                return post.get('title').indexOf(value) !== -1;
              }
            });
          }
          break;
      }
      
    }

更新计算属性以使用新的过滤器对象并监听数组中每个项目的更改

  filteredContent: function () {
    var ret = this.get('arrangedContent');
    var filters = this.get('filters');

    filters.forEach(function (filterObj) {
      ret = ret.filter(filterObj.filter);
    }, this);
    return ret;
  }.property('arrangedContent', 'filters.@each'), // <-- notice the new @each

关于javascript - Ember Controller 计算属性(对象类型)更新不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26793012/

相关文章:

javascript - 将 JSON 结果绑定(bind)到下拉列表

javascript - 如何对数组的数组求和?

javascript - THREE.js稀疏平面BufferGeometry

javascript - 尝试在有丝 split 模拟中模拟细胞的 split

ember.js - 为 ember 夹具数据添加延迟以模拟 ajax

javascript - jquery 函数不工作不会显示警报

javascript - 嵌套多栏导航

ember.js - 使用 Firebase Simple Login 保护路由

ember.js - 如何通过 GUID 查找 Ember 对象? (使用 Em.guidFor 检索)

javascript - 需要在下拉选项中创建评论