英文原址:http://emberjs.com/guides/object-model/classes-and-instances/
Class and Instance(类和实例)
定义一个新的Ember类,可以调用Ember.Object的extend()方法。
App.Person = Ember.Object.extend({
say: function(thing) {
alert(thing);
}
});
上面的代码定义了一个App.Person类,带有一个say()方法。
你可以调用任何已有的类的extend()方法来创建一个该类的子类。比如说,你可能想创建一个Ember内建的Ember.View类的子类:
App.PersonView = Ember.View.extend({
tagName: 'li',
classNameBindings: ['isAdministrator']
});
当你定义子类时,你可以重写父类中的方法,但你仍然可以通过_super()方法来调用该方法在父类中的实现:
App.Person = Ember.Object.extend({
say: function(thing) {
var name = this.get('name');
alert(name + " says: " + thing);
}
});
App.Soldier = App.Person.extend({
say: function(thing) {
this._super(thing + ", sir!");
}
});
var yehuda = App.Soldier.create({
name: "Yehuda Katz"
});
yehuda.say("Yes"); // alerts "Yehuda Katz says: Yes, sir!"
Creating Instances(创建实例)
一旦你定义了一个类,你可以通过调用它的create()方法来创建一个该类的实例。任何定义在该类上的方法,属性和计算型属性都可以通过这个实例使用:
var person = App.Person.create();
person.say("Hello"); // alerts " says: Hello"
在你创建实例的时候,你可以通过传递一个可选的hash参数给create()方法来初始化它的属性值。
App.Person = Ember.Object.extend({
helloWorld: function() {
alert("Hi, my name is " + this.get('name'));
}
});
var tom = App.Person.create({
name: "Tom Dale"
});
tom.helloWorld(); // alerts "Hi, my name is Tom Dale"
因为性能的原因,当你调用create()方法的时候,你不可以重定义该实例的计算型属性或者方法,你也不能定义新的计算型属性或者方法,你只能设置一些简单类型的属性。如果你需要重定义或者新定义方法或者计算型属性,你应该创建一个新类并实例化这个新类。
按照约定,用来存储类数据的属性或者变量应该按照Pascal方式来命名,实例不需要遵守这个约定。因此,比方说,变量App.Person会指向一个类定义,而person会指向一个类定义的实例(通常是App.Person类)。你应该在你的Ember应用中遵守这个约定。
Initializing Instances(初始化实例)
当一个新的实例被创建时,它的init方法会被自动调用。这是个理想的地方去做你想要的初始化工作:
App.Person = Ember.Object.extend({
init: function() {
var name = this.get('name');
alert(name + ", reporting for duty!");
}
});
App.Person.create({
name: "Stefan Penner"
});
// alerts "Stefan Penner, reporting for duty!"
如果你为框架中的某个类创建子类,比如说Ember.View或者Ember.ArrayController,并且你重写了init方法,请确保你会在你子类的init方法中使用this._super()来调用它父类的方法。如果你不这么做,Ember框架就没有机会做一个重要的创建工作,你的应用就会出现一些非常奇怪的行为。
当访问一个对象的属性是,一定要使用get和set方法:
var person = App.Person.create();
var name = person.get('name');
person.set('name', "Tobias Fünke");
务必使用这些访问器方法,否则,计算型属性不会被重新计算,观察事件也不会被触发,使用相关属性的模板也不会被更新。