Ember JS提供一套自己的類系統(tǒng),普通的JavaScript
標(biāo)準(zhǔn)類不能自動更新屬性值,Ember JS的類會自動觸發(fā)觀察者,自動更新屬性值、自動刷新模板上的屬性值。如果一個類是Ember JS提供的可以看到前綴命名空間是Ember.Object
。
Ember
類定義使用extend()
方法,創(chuàng)建類實例使用create()
方法,可以在方法傳入?yún)?shù),但是參數(shù)要以hash
列表方式傳入。
Ember JS重寫了標(biāo)準(zhǔn)JavaScript
的數(shù)組類Array
,并且為了與標(biāo)準(zhǔn)JavaScript
類區(qū)別命名為Ember.Enumerable
(API介紹)
Ember JS還擴展了String
屬性的特性,提供了一系列特有的處理方法,API介紹。
關(guān)于類的命名規(guī)則在此不做介紹,自己網(wǎng)上找一份Java
的命名規(guī)則的教材看看即可。
開始之前先做好準(zhǔn)備工作,首先創(chuàng)建一個HTML文件,并引入Ember JS所必須的文件(后面會介紹一種更加簡單的方法去搭建EmberJS
的項目方法,當(dāng)然如果你有時間也可以提前去了解,這種方式是使用Ember CLI
搭建EmberJS
的項目)。
Ember.js ? Guides
// 在這里編寫Ember代碼
上面代碼是一個簡單的HTML
文件,所需的Ember
庫直接使用CDN
。
下面定義一個Person
類,定義方式如下:
Person?=?Ember.Object.extend({
??say(thing)?{
????alert(name);
??}
});
上面代碼定義了一個Person
類,并且在類里面還定義了一個方法say
,方法傳入一個參數(shù)thing
。方法體僅僅是打印了傳入的參數(shù)。
在子類重寫父類的方法,并在方法里調(diào)用_super()
方法來調(diào)用父類中對應(yīng)的方法觸發(fā)父類方法的行為。
Person?=?Ember.Object.extend({
????
??say(thing)?{
????var?name?=?this.get('name');
????alert(name?+?"?says:?"?+?thing);
??}
});
Soldier?=?Person.extend({
????
??say(thing)?{
????//?this?will?call?the?method?in?the?parent?class?(Person#say),?appending
????//?the?string?",?sir!"?to?the?variable?`thing`?passed?in
????this._super(thing?+?",?sir!");
??}
});
var?yehuda?=?Soldier.create({
??name:?"Yehuda?Katz"
});
yehuda.say("Yes");?//?alerts?"Yehuda?Katz?says:?Yes,?sir!"
運行代碼,刷新瀏覽器,可以看到如下結(jié)果:
結(jié)果正確了,但是我們還不知道類是怎么初始化的,它初始化的順序又是怎么樣的呢?其實每個類都有一個默認(rèn)的初始化方法,555……別急,接著往下看。
要獲取一個類的實例只需要調(diào)用類的create()
方法即可。
Person = Ember.Object.extend({
show() {
console.log("My name is " + this.get('name'));
}
});
var person = Person.create({
name: 'ubuntuvim'
});
person.show(); // My name is ubuntuvim
var person2 = Person.create({
pwd: 'ubuntuvim'
});
// 由于創(chuàng)建person2的時候沒有設(shè)置name的值,默認(rèn)是undefined
person2.show(); // My name is undefined
注意:處于性能的考慮在使用create()
方法創(chuàng)建實例的時候,不允許新定義、重寫計算屬性,也不推薦新定義、重寫普通方法,Ember
推薦在使用create()
方法時只是傳遞簡單的參數(shù),比如上述代碼的{name: 'ubuntuvim'}
。如果你需要新地定義、重寫方法請新建一個子類來實現(xiàn)。
在create()
方法內(nèi)定義計算屬性,運行后會直接報如下圖的報錯信息。
Person = Ember.Object.create({
show() {
console.log("My name is " + this.get('name'));
},
fullName: Ember.computed(function() {
console.log("computed properties.");
})
});
前面提過,我們在類繼承的時候到底類是怎么初始化,這節(jié)就介紹類的初始化,Ember
定義了一個init()
方法,此方法在類被實例化的時候自動調(diào)用。
Parent = Ember.Object.extend({
init() {
console.log("parent init...");
},
show() {
console.log("My name is " + this.get('name'));
},
others() {
console.log("the method in parent class..");
}
});
//parent = Parent.create({
// name: 'parent'
//});
Child = Parent.extend({
init() {
console.log("child init...");
},
show() {
this._super();
}
});
child = Child.create({
name: 'child'
});
child.show();
child.others();
注意:init()
方法只有在類的create()
方法被調(diào)用的時候才會被自動調(diào)用,上面的例子中,如果只是child.others()
這個方法父類并不會調(diào)用init()
方法,只有執(zhí)行Parent.create()
這個調(diào)用的時候才會執(zhí)行init()
方法。
上面代碼如果把Parent.create()
這幾句代碼注釋掉得到的結(jié)果如下:
可見父類的init()
方法沒有被調(diào)用,然后修改代碼,注釋掉child.others()
這句,再把Parent.create()
這幾句的注釋去掉。得到如下結(jié)果
可以看到父類的init()
方法被調(diào)用了!由此可見init()
方法是在調(diào)用create()
方法的時候才調(diào)用的。
在項目中有可能你需要繼承Ember
提供的組件,比如繼承Ember.Component
類,此時你就要注意了,在你繼承Ember
的組件的時候你必須顯式的調(diào)用父類方法this._super()
否則你繼承得到的類無法獲取Component
提供的行為或者得到無法預(yù)知的結(jié)果。
Ember
建議訪問類的屬性使用get、set
方法。如果你直接使用obj.prop
這種方式訪問也是可以得到類的屬性值,但是如果你不是使用訪問器操作的就會導(dǎo)致很多問題:計算屬性不能被重新計算、無法察覺對象屬性的變化、模板也不能自動更新。
Person = Ember.Object.extend({
name: 'ubuntuvim'
});
// Ember 推薦的訪問方式
var person = Person.create();
console.log("My name is " + person.get('name'));
person.set('name', "Tobias Funke");
console.log("My name is " + person.get('name'));
console.log("---------------------------");
// 不推薦的方式
var person2 = Person.create();
console.log("My name is " + person2.name);
person2.name = "Tobias Funke";
console.log("My name is " + person2.name);
Ember為我們封裝了get、set
實現(xiàn)細(xì)節(jié),開發(fā)者直接使用即可。
最后感謝唯獨莪靑睞的指正。
博文完整代碼放在Github(博文經(jīng)過多次修改,博文上的代碼與github代碼可能又出入,不過影響不大?。绻阌X得博文對你有點用在github項目上給我個star
吧。您的肯定對我來說是最大的動力??!
更多建議: