12

我发现关于 Ember 非常违反直觉的一点是,您可以使用create(). 见http://jsfiddle.net/zJQJw/2/

我发现最好的解决方法是调用create().setProperties(properties)而不是调用create(properties),但这对我来说似乎是一个不必要的问题。我意识到此时它可能会破坏某些应用程序,但是您会考虑让create()行为更像setProperties()吗?

我提出这个要求的动机是在使用该模式init()之前会调用它。这还不是一个大问题,但我可以看到这在某些情况下是不可取的。这是一个完全人为的例子,但也许你能看到我在说什么?http://jsfiddle.net/QJ8vX/2/setProperties()create().setProperties(properties)

我可以看到保持当前行为的唯一原因是对 setter 方法进行特定于实例的覆盖。但在这些情况下,你可以很容易地做到MyClass.extend({ overridenMethod: ... }).create(properties)

Ember 1.0 会考虑这样的改变吗?还是我对 Ember 的对象模型应该如何工作有错误的想法?

4

2 回答 2

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语义
  • 添加一个新的 API (overridecreateWithOverride) 来保留现有的语义,以防您明确想要覆盖现有的计算属性
  • 抑制因create(或决定不)设置的属性的观察者
  • 找到一种方法来检测并警告尝试将createAPI 与未实现 setter 的计算属性一起使用。

我需要更多地讨论它,并考虑对现有应用程序的影响,但这绝对是值得考虑的事情,因为它对于新开发人员来说绝对是一个很大的问题。我们需要改变行为的事实ember-data是一个很好的线索,表明有些事情不太正确。

于 2012-07-18T01:44:35.857 回答
4

这可能是一个肮脏的黑客,但它对我有用。

Em.Object.reopenClass({ 
   create: function(config) {
       return this._super().setProperties(config); 
   }
});
于 2012-11-18T15:20:31.380 回答