Ember.js 入門指南 (二)
@(Ember)[MVVM|前端框架|HTML桌面應用]
序言
經常有人質疑,在前端搞MV*有什麼意義?也有人跟我提出這樣的疑問:以AngularJS,Knockout,BackBone為代表的MV*框架,它跟jQuery有什麼區別?我jQuery用得好好的,有什麼必要再引入這種框架?
其實,不管我們使用的是一個類庫還是一個框架,都不應該忘記我們最終目的,或許你正在為一個專案做技術選型,或許你正在為你的應用考慮程式碼重構,又或許你只是單純的想做一些學術性研究,所以框架和類庫的選擇沒有絕對只有最適合。
以jQuery為代表,針對介面上常見的DOM操作,遠端請求,資料處理等作了封裝,也有專注於處理資料的
EMBER物件模型
Ember增強了簡單的JavaScript物件模型,使之能夠支援繫結和觀察者,同時也支援一種更加強大的、基於混合的(mixin-based)程式碼共享途徑。
作為最基本的形式,你可以使用Ember.Object
的extend
方法建立一個新的Ember類。
Person = Ember.Object.extend({
say: function(thing) {
alert(thing);
}
});
一旦你成功建立了一個新類,就可以使用create來建立類的例項了。類中定義的任何屬性在例項中都是可用的。
var person = Person.create();
person.say("Hello") // alerts "Hello"
建立例項時,也可以通過傳入物件來為例項增添額外的屬性。
var tom = Person.create({
name: "Tom Dale",
helloWorld: function() {
this.say("Hi my name is " + this.get('name'));
}
});
tom.helloWorld() // alerts "Hi my name is Tom Dale"
由於Ember支援繫結和觀察者,因此你可以隨時通過get方法訪問屬性,也可以通過set方法設定屬性。
當建立一個物件的新的例項時,也可以覆寫類中定義的任何屬性和方法。在本例中,作為例子,你可以覆寫從Person
類繼承的say
方法。
var yehuda = Person.create({
name: "Yehuda Katz",
say: function(thing) {
var name = this.get('name');
this._super(name + " says: " + thing);
}
});
你可以使用物件的_super
方法(super是JavaScript中的保留字)來呼叫被你覆寫的原始方法。
類的子類
你也可以使用extend方法為類建立子類。事實上,我們上面使用Ember.Object物件的extend方法建立新類時,即是建立了Ember.Object的子類。
var LoudPerson = Person.extend({
say: function(thing) {
this._super(thing.toUpperCase());
}
});
當建立子類時,你可以使用this._super
來呼叫被你覆寫的方法。
重新開啟類和例項
無需一次性將類定義完全,你可以使用reopen
方法來重新開啟(reopen)一個類併為其定義新的屬性。
當使用reopen
時,你也同樣可以覆寫已經存在的方法並呼叫this._super
。
Person.reopen({
// override `say` to add an ! at the end
say: function(thing) {
this._super(thing + "!");
}
});
正如你所見,reopen
是用來為例項新增屬性和方法的。而當你需要建立類的方法或為類本身新增屬性時,則可使用reopenClass
。
Person.reopenClass({
createMan: function() {
return Person.create({isMan: true})
}
});
Person.createMan().get('isMan') // true
計算屬性 (Getters)
你可能經常需要一個基於其他屬性計算而來的屬性。Ember的物件模型可以使你很輕鬆地在常規的類定義中定義計算屬性。
Person = Ember.Object.extend({
// these will be supplied by `create`
firstName: null,
lastName: null,
fullName: function() {
var firstName = this.get('firstName');
var lastName = this.get('lastName');
return firstName + ' ' + lastName;
}.property('firstName', 'lastName')
});
var tom = Person.create({
firstName: "Tom",
lastName: "Dale"
});
tom.get('fullName') // "Tom Dale"
當為類建立子類或者新的例項時,你可以覆寫任何計算屬性。
計算屬性 (Setters)
你也可以定義當設定計算屬性時Ember所執行的動作。當你嘗試設定計算屬性時,可以使用對應的名-值(key and value)對其進行設定。
Person = Ember.Object.extend({
// these will be supplied by `create`
firstName: null,
lastName: null,
fullName: function(key, value) {
// getter
if (arguments.length === 1) {
var firstName = this.get('firstName');
var lastName = this.get('lastName');
return firstName + ' ' + lastName;
// setter
} else {
var name = value.split(" ");
this.set('firstName', name[0]);
this.set('lastName', name[1]);
return value;
}
}.property('firstName', 'lastName')
});
var person = Person.create();
person.set('fullName', "Peter Wagenet");
person.get('firstName') // Peter
person.get('lastName') // Wagenet
對於setter和getter,Ember都會呼叫計算屬性,你可以通過檢查引數的個數來確定該計算屬性究竟是被getter還是setter呼叫的。
觀察者
Ember支援觀察任何屬性,包括計算屬性。你可以使用addObserver
方法在某個物件上設定觀察者。
Person = Ember.Object.extend({
// these will be supplied by `create`
firstName: null,
lastName: null,
fullName: function() {
var firstName = this.get('firstName');
var lastName = this.get('lastName');
return firstName + ' ' + lastName;
}.property('firstName', 'lastName')
});
var person = Person.create({
firstName: "Yehuda",
lastName: "Katz"
});
person.addObserver('fullName', function() {
// deal with the change
});
person.set('firstName', "Brohuda"); // observer will fire
由於fullName
這個計算屬性依賴於firstName
,所以更新firstName
也會觸發fullName
上的觀察者。
由於觀察者的應用非常普遍,Ember提供了一種能夠在類定義的內部定義觀察者的方式。
Person.reopen({
fullNameChanged: function() {
// this is an inline version of .addObserver
}.observes('fullName')
});
繫結
繫結在兩個屬性之間建立了一個連線,這樣一個屬性改變時另一個也可以隨之自動更新到最新的值。繫結也可以連線同一物件內的屬性,或者跨越兩個不同的物件。與其他大部分框架所包含的繫結實現不同的是,Ember.js的繫結可以用在任何物件上,而不僅僅用在檢視和模型之間。
最簡單的建立雙向繫結的方法是,建立一個以Binding
字串結尾的屬性,然後指定一個相對於全域性作用域(global scope)的路徑:
App.wife = Ember.Object.create({
householdIncome: 80000
});
App.husband = Ember.Object.create({
householdIncomeBinding: 'App.wife.householdIncome'
});
App.husband.get('householdIncome'); // 80000
// Someone gets raise.
App.husband.set('householdIncome', 90000);
App.wife.get('householdIncome'); // 90000
注意這個繫結不會立即更新,Ember會等待應用的所有程式碼執行完成之後再同步變更,因此你可以隨意改變某個繫結的屬性,而不用擔心同步這些臨時值所耗費的開銷。
單向繫結
單向繫結只將變更單向傳播。通常,單向繫結只是為了效能優化,你可以放心地使用更加簡潔的雙向繫結語法(當然,如果你總是隻改變一邊的話,那麼雙向繫結事實上也是單向綁定了)。
App.user = Ember.Object.create({
fullName: "Kara Gates"
});
App.userView = Ember.View.create({
userNameBinding: Ember.Binding.oneWay('App.user.fullName')
});
// Changing the name of the user object changes
// the value on the view.
App.user.set('fullName', "Krang Gates");
// App.userView.userName will become "Krang Gates"
// ...but changes to the view don't make it back to
// the object.
App.userView.set('userName', "Truckasaurus Gates");
App.user.get('fullName'); // "Krang Gates"
應用程式 APPLICATION
根據你的需求,有幾種方式可以建立你的第一個Ember App.
如果你的需求較簡單或者只是感興趣隨便玩玩,你可以下載Ember.js入門套件(Starter Kit),該入門套件基於HTML5 樣板,無需任何構建工具、沒有其他依賴。你也可以使用一些其他前端Scaffold工具來構建你的ember應用(例如: Yoeman )。當然你也可以根據自己的專案特點來構建自己的應用。
建立一個應用程式
每個Ember app
都應該有一個Ember.Application
的例項。這個物件將會作為你的app中所有類和例項的全域性可訪問的名稱空間(globally-accessible namespace)
。此外,它也在頁面上設定了事件監聽器,確保當用戶與你的使用者介面進行互動時你的檢視可以接收到事件。
建立Ember.js應用程式的第一步是建立一個Ember.Application
類的例項化物件:
window.App = Ember.Application.create();
這裡將例項化的物件命名為App,開發者可以根據應用程式的用途,選擇意義相符的名字。
建立一個應用程式的例項物件非常重要,原因如下:
定義應用程式的名稱空間,所有類都定義成該物件的屬性(比如App.PostsView、App.PostsController)。這樣做可以避免汙染全域性作用域。
在document上增加事件監聽,並負責將事件傳送給檢視。
自動渲染模板,包括根模板,以及其他放入根模板的模板,都將被渲染。
基於當前URL建立路由器並開始路由。
Person.reopenClass({
createMan: function() {
return Person.create({isMan: true})
}
});
Person.createMan().get('isMan') // true
你可以隨意為你的名稱空間命名,不過必須以大寫字母開頭,這樣繫結才能找到它。
如果要將Ember應用嵌入到某個現存的網站中,可以通過提供rootElement屬性來將某個特定的元素作為事件監聽器。
小結:
使用計算屬性建立由其他屬性綜合決定的新屬性。
計算屬性不應該包含應用的行為,而且當呼叫時不應有任何附加影響。
除非在極少數情況下,多次呼叫相同的計算屬性應該總是返回同樣的值(當然,除了屬性所依賴的屬性值改變的情況。)
觀察者應該包含反映其他屬性變化的行為。
當你需要在繫結完成同步之後執行一些行為的時候,觀察者會非常有用。
繫結通常用在確保位於不同層的物件總能保持同步。
例如,你使用
Handlebars
綁定了你的檢視和控制器,你也可能經常需要繫結同一層的兩個物件。例如,你可能有個
App.selectedContactController
需要繫結在App.contactsController
的selectedContact
屬性上
相關推薦
Ember.js 入門指南 (二)
@(Ember)[MVVM|前端框架|HTML桌面應用] 序言 經常有人質疑,在前端搞MV*有什麼意義?也有人跟我提出這樣的疑問:以AngularJS,Knockout,BackBone為代表的MV*框架,它跟jQuery有什麼區別?我jQuery用
Maven入門指南(二)
deploy ... web服務器 快速 repos 必須 轉載 關於 net 轉載自並發編程網 – ifeve.com本文鏈接地址: Maven入門指南(二) Maven目錄結構 Maven有一個標準的目錄結構。如果你在項目中遵循Maven的目錄結構,就無需在pom文件中
require.js 入門講解(二)
require.js使用AMD體系,採用非同步方式載入模組,即模組的載入不影響,載入程式碼後面語句的執行,採用回撥函式方式在模組載入完畢後執行回撥函式,語法如下示意: require([module], callback); 該語法說明如下: module代表需要載入的
Drools規則引擎入門指南(二)
本篇部落格主要講解Drools常用的屬性以及函式 屬性 首先我們在resources\rules資料夾下建立一個Property.drl,還有一個DroolsApplicationPropertyTests 1. salience優先順序 salience 屬性的值預設為0,它的值越大執行的
機器學習之python入門指南(二)元組、集合、字典的使用
Python3中元組、集合、字典的使用 Python中元組的用法元組的建立與訪問 元組和列表類似,不同之處在於元組不能修改,元組使用小括號,列表使用方括號,注意元組中如果只包含以個元素需要在後面加,否則會被當作運算子使用 元組與字串類似,下標索引從0開始,可以進行擷取,取捨
RequireJS入門指南(二)-vue分頁模組抽離
vue實現分頁,模組化實現的碎碎念。 這篇講一下我是如何在專案中抽離出分頁模組的。 這段時間做的專案讓我很頭疼,因為前面寫程式碼的時候沒有考慮很多東西,寫到後面就發現程式碼越來越重。 而且在不同頁
Gradle入門指南(二)
轉載請標明出處: 本文出自:【ouyida3的部落格】 注意:本文內容都是通過gradle命令列完成,不涉及eclipse的外掛。 1、先閱讀 2、常用命令 gradle -v gradle build gradle build --
redis入門指南(二)—— 資料操作相關命令
寫在前面 以下絕大部分內容取材於《redis入門指南》,部分結合個人知識,實踐後得出。 只記錄重要,明確,屬於新知的相關內容,杜絕冗餘和重複。 字串 1、字串型別是redis中最常見的型別,目前字串資料的最大容量是512M。 2、取值、賦值 SET key value
給萌新HTML5 入門指南(二)
本文由葡萄城技術團隊原創並首發 轉載請註明出處:葡萄城官網,葡萄城為開發者提供專業的開發工具、解決方案和服務,賦能開發者。 上一篇我們已經為大家介紹了HTML5新增的內容和基礎頁面佈局,這篇會繼續向大家介紹廣義上HTML5中另一個組成部分:JavaScript資料型別。 JavaScri
Ember.js 入門指南——控制器(controller)
ember new chapter5_controllers cd chapter5_controllers ember server 從本篇開始進入第五章控制器,controller在Ember2.0開始越來越精簡了,職責也更加單一——處理邏輯。 下面是準備工作。
Ember.js 入門指南——繫結(bingding)
正如其他的框架一樣Ember也包含了多種方式繫結實現,並且可以在任何一個物件上使用繫結。也就是說,繫結大多數情況都是使用在Ember框架本身,對於開發最好還是使用計算屬性。 1,雙向繫結 // 雙向繫結 Wife = Ember.Object.extend(
three.js 入門指南(敷衍一下)
今天看了一本好書three.js,感覺特別適合我這種對three.js 瞭解不深的人。 其實要學習three.js,還有許多其他方面的知識要了解,例如如何繪製多邊形,如何繪製曲線,攝像機的一些基礎知識等等。 推薦一本老外的three.js指南 https://pan.baidu.com/
條形碼入門指南(八):二維條形碼
現在條形碼無處不在,幾乎用於所有業務領域的識別。在業務流程中實施條形碼時,可以自動執行程式以減少人為錯誤
Asp.Net Core WebAPI入門整理(二)簡單示例
序列 open exc tor pda template ssa net found 一、Core WebAPI中的序列化 使用的是Newtonsoft.Json,自定義全局配置處理: // This method gets called by the runtime.
Struts2入門介紹(二)
輸入 clu ons dom 訪問路徑 訪問 filter pri locale 一、Struts執行過程的分析。 當我們在瀏覽器中輸入了網址http://127.0.0.1:8080/Struts2_01/hello.action的時候,Struts2做了如下過程:
Three.js入門篇(一)創建一個場景
style api text webgl () mes utf 動畫 fun 上一面講述了向場景中添加物體對象。這一篇準備把每個功能點細細的講述一遍,一方面是為了加深自己的理解。另一方面希望能夠 幫助到有需要的人。 一、在學習WEBGL的時候,你應該先了解要創建一個WebG
CodeArt入門教程(二)
本質 文件夾 不同的 存在 切換數據庫 站點 ear 新的 組裝 4.第一個示例的編碼工作 使用CA編碼項目的核心結構是:由多個子系統組成多個不同的服務來提供項目的各種功能。請不要將這裏提到的子系統與大家在別的項目實施方法裏的概念混為一談,CA裏的子系統概念是完全不一樣
OpenCV入門筆記(二) 圖片的文件操作
strong asc nump str destroy type convert 代碼 creat 以下介紹一下重要的幾個,設計基本 圖片處理 的函數,依次來了解OpenCV的入門知識。具體的具體使用方法還是以官方的API【Official Tutori
Dapper入門教程(二)——執行非查詢語句
文本 resp -exec factor -h spa onf fec table 描述 你可以從任意實現IDbConnection的類對象中調用Dapper的擴展方法“Execute”。它能夠執行一條命令(Command)一次或者多次,並返回受影響的行數。這個方法通常用來
MVC5+EF6入門記(二)
key 元素 action 地址 登錄ui acc 場景 stact name 貓和你都歸我 2017/10/01 17:00:29 今天學習了第二課的內容,下面是我總結的知識點,希望會有所幫助,也希望多多指導!一、對專業名詞的解釋Action Method Selec