我试图从控制器动态更新组件值,而不是通过模板显式传递值。以下硬编码解决方案有效:
foo: Em.computed.oneWay('bar')
但是,我希望有这样的事情:
slab: 'bar',
foo: Em.computed.oneWay(slab)
将值绑定在一起非常重要,而不仅仅是组件启动时的初始值。有没有办法做到这一点?
答案 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')
要完成它:
创建控制器并且slab
未定义。某些因素会导致slab
更改,从而触发_slabDidChange
观察者。 (请注意,我们在property
上使用observes
而非_slabDidChange
,因为前者会导致函数过早被调用。Source)
_slabDidChange
开火。它跳过了删除旧的观察者,因为我们尚未创建一个。然后它添加了一个新的观察者,观察slab
属性所持有的属性。然后它存储密钥和观察者,以便我们以后删除它们。
foo
都会更新。在您的示例中,随时bar
更新,foo
更新。
如果slab
发生了变化,重复步骤2,则只会先删除旧观察者,以免foo
发生冲突更新。
您的想法是必须手动将观察者添加到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
。