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

时间:2015-02-18 22:22:24

标签: javascript node.js ember.js

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

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. 有没有更简单的方法来解决这个问题?我觉得我忽视了一些简单的事情。

2 个答案:

答案 0 :(得分:3)

关于问题#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,我无法想到更简单的解决方案。

答案 1 :(得分:1)

我不得不对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')