如何初始化控制器的计算 属性 以在 Ember 中建模?

How to initialize a Controller's computed property to model in Ember?

我在 Ember 控制器上定义了一个计算 属性 myArray,returns 一个数组。该数组应初始化为 model 的内容,然后根据用户输入的查询通过过滤 model 重新计算。

myArray: function() {
  // return a value that filters model with query
}.property('model', 'query')

问题是我不知道如何同时做这两件事。以下无法将 myArray 初始化为 model;我猜是因为模型是异步加载的,init() 在完成之前运行。

// doesn't work
init: function() {
  this._super();
  this.set('myArray', this.get('model'));
}

所以我认为 setupController() 应该是设置它的地方,但我发现在那里设置 myArray 导致过滤器更新不起作用,可能是因为我覆盖了定义。

// route definition...
setupController: function(controller, model) {
  controller.set('model', model);
  controller.set('myArray', model);  // breaks updating
}

我怎样才能实现我的目标?

尝试:

myArray: function() {
  this.set('myArray', this.get('model');
}.property('model', 'query')

你想要一个计算 属性 取决于 model - 你不必初始化它,它只需要 return 正确的东西。

// untested, just to show the idea
myArray: function() {
   var query = this.get('query');
   var model = this.get('model');

   if (query) 
      return doSomethingWith(model, query);
   else
      return model;
}.property('model', 'query')

因为它是 属性,初始化和更新将自行进行。

也就是说,Twitter 的传说是不鼓励使用 .property,最好使用 Ember.computed

// untested, just to show the idea
myArray: Ember.computed('model', 'query', function() {
   var query = this.get('query');
   var model = this.get('model');

   if (query) 
      return doSomethingWith(model, query);
   else
      return model;
})

这只是另一种写法,从长远来看可能更适合未来 运行。

编辑:我不知道为什么我会采用迂回的做事方式。我想我只是想说明计算属性也充当设置器。这也将以相同的方式工作:

myArray: function() {
    return this.get('model').filter(function(item) {
        return (item.property_you_want_to_filter_by === true);
    });
}.property('model.@each.property_you_want_to_filter_by', 'query')

Ember shorthand 也适用:

myArray: Ember.computed.filter('model', function(item) {
    return (item.property_you_want_to_filter_by === true);
});

您需要利用计算属性是 getters and setter 的事实。

myArray: function(key, value) {
    // This is the setter
    if (arguments.length > 1) {
        this.set('_myArray', value);
    }

    // This is the getter
    // Do your filtering with `query` here
    return this.get('_myArray').filter(function(item) {
        return (item.selected === true);
    });
}.property('_myArray', 'query')

由于您只在获得新模型时设置它,因此您可以将该值存储在控制器上的私有 属性 中(在本例中为 _myArray)。然后对于 getter,您可以将存储在 属性 中的值与您的查询结合使用以 return 您想要的值。在我上面的示例中,我过滤掉了所有未选择的项目。