Ember – 自定义计算属性检查是否所有依赖字段存在

我正在创build一个表单,我试图find一个简单,优雅的处理方式来查看是否存在所有的input。

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个部分)。

我正在考虑尝试创build一个适合我需要的可重复使用的计算属性。 以我的目标代码为例:

 Form = Ember.Object.extend({ // properties... isComplete: Ember.computed.and('_isSection1Complete', '_isSection2Complete'), _isSection1Complete: Ember.computed.allPresent('name', 'age', 'isABoolean'), _isSection2Complete: Ember.computed.allPresent('job', 'numberOfSiblings') }); 

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

两个问题:

  1. 哪里是定义自定义计算属性的最佳位置? 我可以只附加一个functionEmber.computed
  2. 有一个更简单的方法来解决这个问题吗? 我觉得我正在俯视一些简单的事情。

至于问题#1,

您可以在App名称空间中定义一个自定义的计算助手。 在这个例子中,我创build了一个名为allPresent的新的计算allPresent帮手,它检查传递给allPresent每个属性。

 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,我想不出一个更简单的解决scheme。

我不得不对Evan的解决scheme做一个小小的调整,但是这对于需要它的其他人来说是完美的。

 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')