EmberJS:数组作为带有setter的计算属性

时间:2014-05-08 01:26:54

标签: ember.js

我在计算属性上有一个setter的问题,这是一个数组。似乎没有为数组触发setter。

这是一个最小化的代码,仅用于演示我的问题。还有一个JSFiddle:http://jsfiddle.net/NQKvy/970/

App.People = DS.Model.extend({
    array1: DS.attr('array', {defaultValue: [{name: 'Hans Maulwurf'},
                                             {name: 'Karl Käfer'}]}),

    array2: function(key, value){
        var array1 = this.get('array1'),
            array2 = [];

        if (arguments.length === 2) {
            this.set('array1', value);
        }

        if (array1 === undefined || typeof array1 === null) {
            return null;
        }

        $.each(array1, function(index, value){
            array2.pushObject( {name: value.name} );
        });

        return Ember.isNone(array2) ? null : array2;
    }.property('array1.@each')
});

App.IndexRoute = Ember.Route.extend({
    model: function(){
      return this.store.createRecord('people', {
      })
  }
});

App.IndexController = Ember.ObjectController.extend({
    actions: {
        newPerson1: function() {
            this.get('model.array1').pushObject({name: 'Klaus Kobold'});
        },
        newPerson2: function() {
            this.get('model.array2').pushObject({name: 'Klaus Mann'});
        }
    }
});

当我把一个人推到array1时,一切都很好。计算属性已正确更新。但是,当我将一个人推送到array2(计算属性)时,即使这样实现了setter,array1也不会更新。

通常,通过计算属性(http://emberjs.com/guides/object-model/computed-properties/#toc_setting-computed-properties)更新属性没有问题。但在这种情况下,EmberJS在更改阵列时没有设置值。

我犯了错误还是在EmberJS中真的不可能?如果是这样,你知道如何实现这个目标吗?

我必须通过计算属性更改数组。我的用例没有其他办法。


更新

正如kingpin2k指出的那样,当没有为整个数组设置新值而是将新元素推送到现有数组时,它只是一个问题。我更新了JSFiddle来演示差异:http://jsfiddle.net/NQKvy/972/正如您所看到的,当通过changePerson2操作将新值设置为array2时,array1已更新,但在newPerson2将新元素推送到数组时未更新1}}行动。

我发现有一个肮脏的解决方法。将元素推送到数组后,我可以再次设置计算属性:

this.get('model.array2').pushObject({name: 'Detlef Workaround'});
this.set('model.array2', this.get('model.array2'));

小提琴中的行动dirtyWorkaround正在证明这一点。但是还有另一种方式吗?

关于我的用例的几句话:我使用计算属性来加密/解密数据。发送到服务器的普通属性使用Stanford Javascript Crypto Library(SJCL)加密。解密/加密由计算属性处理。因此应用程序通过计算属性访问所有数据这对于数据类型String,Date等完全正常。我只遇到数组问题。

1 个答案:

答案 0 :(得分:0)

为了完整起见,您需要在数组上添加一个数组观察器,并在该数组发生更改时更新另一个数组。

array.addArrayObserver(contextToBindTo,{
  willChange: function(observedObj, start, removeCount, addCount){  }, 
  didChange: function(observedObj, start, removeCount, addCount){ }
});

这是一个例子

http://emberjs.jsbin.com/wifovebu/1/edit