【问题标题】:How to initialize a Controller's computed property to model in Ember?如何初始化控制器的计算属性以在 Ember 中建模?
【发布时间】:2015-04-07 06:58:48
【问题描述】:

我在 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
}

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

【问题讨论】:

    标签: ember.js


    【解决方案1】:

    您想要一个取决于 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;
    })
    

    这只是另一种编写方式,从长远来看可能更适合未来。

    【讨论】:

    • 设置值不会覆盖计算属性,它会像setter一样调用计算属性,如here解释的那样。
    • 我的错。感谢您指出。我已更改答案以反映这一点。
    【解决方案2】:

    尝试:

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

    【讨论】:

      【解决方案3】:

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

      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,您可以使用存储在该属性中的值与您的查询相结合来返回您想要的值。在上面的示例中,我过滤掉了所有未选择的项目。

      【讨论】:

      • “Ember 速记”缺少“模型”作为第一个参数。也就是说,如果过滤器确实是包含的过滤器功能支持的某种逻辑,那么这确实是最短的版本。
      猜你喜欢
      • 2014-05-26
      • 2017-05-21
      • 1970-01-01
      • 2014-07-05
      • 1970-01-01
      • 2014-10-15
      • 2014-08-19
      • 2016-02-05
      • 1970-01-01
      相关资源
      最近更新 更多