动态计算别名

时间:2014-04-16 10:32:41

标签: ember.js

我试图从控制器动态更新组件值,而不是通过模板显式传递值。以下硬编码解决方案有效:

foo: Em.computed.oneWay('bar')
但是,我希望有这样的事情:

slab: 'bar',
foo: Em.computed.oneWay(slab)

将值绑定在一起非常重要,而不仅仅是组件启动时的初始值。有没有办法做到这一点?

3 个答案:

答案 0 :(得分:1)

2015年1月更新:巧合的是,我在几天前写了一个小插件,以回应Ember Github中的一个问题。 This插件允许您拥有动态计算属性。所以现在这将成为您的解决方案:

slab: 'bar',
foo: Ember.computed.indirect('slab')

这将使两者绑定在一起,因此foo属性将始终指向slab值所指的任何属性。


也许这样的事情(取自你的例子):

slab: function() {
    return mysteryString;
}.property(),

foo: undefined,

_slabObserver: null,
_slabObserverKey: null,
_slabDidChange: function() {
    // Remove the old observer
    if (this.get('_slabObserverKey')) {
        this.removeObserver(this, this.get('_slabObserverKey'), this.get('_slabObserver'));
    }

    // Create the new one
    this.set('_slabObserver', function() {
        // Update foo when the value whose key is held by 'slab' changes
        this.set('foo', this.get(this.get('slab')));
    });
    // Watch the property whose key is held by 'slab' and call the method we just created
    this.addObserver(this, this.get('slab'), this.get('_slabObserver'));

    // Hold the last key so we can remove the observer properly after it changes
    this.set('_slabObserverKey', this.get('slab'));
}.property('slab')

要完成它:

  1. 创建控制器并且slab未定义。某些因素会导致slab更改,从而触发_slabDidChange观察者。 (请注意,我们在property上使用observes而非_slabDidChange,因为前者会导致函数过早被调用。Source

  2. _slabDidChange开火。它跳过了删除旧的观察者,因为我们尚未创建一个。然后它添加了一个新的观察者,观察slab属性所持有的属性。然后它存储密钥和观察者,以便我们以后删除它们。

  3. 每当我们观察到的属性发生变化时,
  4. foo都会更新。在您的示例中,随时bar更新,foo更新。

  5. 如果slab发生了变化,重复步骤2,则只会先删除旧观察者,以免foo发生冲突更新。

  6. 您的想法是必须手动将观察者添加到bar属性。我没有对此进行过测试,但这个想法应该是明确的。

答案 1 :(得分:0)

试试这个:

slab: 'bar',
foo: Em.computed.oneWay(this.slab);

答案 2 :(得分:0)

据我所知,你只能使用计算属性:

foo: function(key, value) {
        var slab = this.get('slab');

        if (arguments.length > 1) {
            this.set(slab, value);
        }

        return this.get(slab);
    }.property('slab')

对于oneWay,您必须更改this.set(slab, value);或删除整个if