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

时间:2015-04-07 06:58:49

标签: ember.js

我在Ember控制器上定义了一个计算属性myArray,它返回一个数组。应该将数组初始化为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
}

我如何实现目标?

3 个答案:

答案 0 :(得分:2)

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

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

这只是另一种写作方式,从长远来看可能是未来的证据。

答案 1 :(得分:1)

尝试:

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

答案 2 :(得分:1)

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

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

您需要利用计算属性为getter 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,您可以使用该属性中存储的值与查询结合使用,以返回所需的值。在上面的例子中,我已经过滤掉了所有未选择的项目。