我发现Ember的反直觉是你可以使用create()
的参数覆盖计算属性设置函数(http://emberjs.com/#toc_computed-properties-setters)。见http://jsfiddle.net/zJQJw/2/
我发现最好的解决方法是拨打create().setProperties(properties)
而不是create(properties)
,但这对我来说似乎是不必要的问题。我意识到此时可能会破坏某些应用,但您是否会考虑让create()
更像setProperties()
?
我要求这样做的动机是init()
在setProperties()
使用create().setProperties(properties)
模式之前会被调用。这还不是一个大问题,但我可以看到在某些情况下这是不可取的。这是一个完全人为的例子,但也许你可以看到我得到了什么? http://jsfiddle.net/QJ8vX/2/
我可以看到维持当前行为的唯一原因是执行特定于实例的setter方法覆盖。但在这些情况下,您可以轻松地执行MyClass.extend({ overridenMethod: ... }).create(properties)
Ember 1.0会考虑这样的变化吗?或者我对Ember的对象模型应该如何运作有错误的想法?
答案 0 :(得分:10)
我们推迟这一变化的主要原因是它无法将基类上定义的属性覆盖为计算属性。例如,在Ember.View
中,template
属性是计算属性:
template: Ember.computed(function(key, value) {
if (value !== undefined) { return value; }
var templateName = get(this, 'templateName'),
template = this.templateForName(templateName, 'template');
return template || get(this, 'defaultTemplate');
}).property('templateName').cacheable(),
创建Ember.View
的子类时,您可能希望使用显式模板函数覆盖此定义:
Ember.View.create({ template: Ember.Handlebars.compile('...') });
如果计算属性不处理setter情况,则覆盖计算属性的尝试将是静默失败。
如果我们进行了此更改,它还会引入有关观察者是否应触发传递到create
方法的属性的其他问题。两者都有可能实现,两种方法都有很强的论据。
在1.0的准备阶段,考虑采用以下方法似乎是合理的:
create
更改为使用setProperties
语义override
或createWithOverride
),以保留现有的语义,以防您明确想要覆盖现有的计算属性create
(或决定不)create
API与未实现setter的计算属性一起使用。我需要更多地讨论它,并考虑对现有应用程序的影响,但它绝对值得考虑,因为它对于新开发人员来说绝对是一个非常大的问题。我们需要改变ember-data
的行为这一事实是一个非常好的线索,表明事情并不完全正确。
答案 1 :(得分:4)
这可能是一个肮脏的黑客,但它对我有用。
Em.Object.reopenClass({
create: function(config) {
return this._super().setProperties(config);
}
});