Ember - 自定义计算 属性 以检查所有相关字段是否存在

Ember - Custom Computed Property to check if all dependent fields exists

我正在创建一个表单,我正在尝试找到一种简单、优雅的处理方式来查看是否所有输入都存在。

Form = Ember.Object.extend({
  // section 1
  name: null,
  age: null,
  isABoolean: null,

  // section 2
  job: null,
  numberOfSiblings: null,

  isComplete: Ember.computed.and('_isSection1Complete', '_isSection2Complete'),

  _isSection1Complete: function() {
    var isPresent = Ember.isPresent;
    return isPresent(this.get('name')) && isPresent(this.get('age')) && isPresent(this.get('isABoolean'));
  }.property('name', 'age', 'isABoolean'),

  _isSection2Complete: function() {
    var isPresent = Ember.isPresent;
    return isPresent(this.get('job')) && isPresent(this.get('numberOfSiblings'));
  }.property('job', 'numberOfSiblings')
});

但是,这似乎无法扩展。我的实际申请会有很多部分(超过20个部分)。

我正在考虑尝试创建一个可重复使用的计算 属性 来满足我的需要。以我想要的代码为例:

Form = Ember.Object.extend({
  // properties...

  isComplete: Ember.computed.and('_isSection1Complete', '_isSection2Complete'),

  _isSection1Complete: Ember.computed.allPresent('name', 'age', 'isABoolean'),

  _isSection2Complete: Ember.computed.allPresent('job', 'numberOfSiblings')
});

我觉得这是一个常见的情况,但是我没有找到关于如何执行它的正确计算属性,所以我想自己做一个。

两个问题:

  1. 定义自定义计算 属性 的最佳位置在哪里?我可以将函数附加到 Ember.computed 吗?
  2. 有没有更简单的方法解决这个问题?我觉得我忽略了一些简单的事情。

至于问题 #1,

您可以在 App 命名空间中定义自定义计算助手。在此示例中,我创建了一个名为 allPresent 的新计算助手,用于检查传入的每个 属性 与 Ember.isPresent.

App.computed = {
  allPresent: function (propertyNames) {
    // copy the array
    var computedArgs = propertyNames.slice(0);

    computedArgs.push(function () {
      return propertyNames.map(function (propertyName) {
        // get the value for each property name
        return this.get(propertyName);
      }, this).every(Ember.isPresent);
    });

    return Ember.computed.apply(Ember.computed, computedArgs);
  }
};

根据您的示例代码,它可以像这样使用:

_isSection2Complete: App.computed.allPresent(['job', 'numberOfSiblings'])

我从这里的方法改编而来:http://robots.thoughtbot.com/custom-ember-computed-properties

至于问题 #2,我想不出更简单的解决方案。

我不得不对 Evan 的解决方案稍作调整,但这对需要它的其他人来说非常有效:

App.computed = {
  allPresent: function () {
    var propertyNames = Array.prototype.slice.call(arguments, 0);
    var computedArgs = propertyNames.slice(0); // copy the array

    computedArgs.push(function () {
      return propertyNames.map(function (propertyName) {
        // get the value for each property name
        return this.get(propertyName);
      }, this).every(Ember.isPresent);
    });

    return Ember.computed.apply(Ember.computed, computedArgs);
  }
};

现在可以这样使用:

_isSection2Complete: App.computed.allPresent('job', 'numberOfSiblings')