action
助手所現(xiàn)實(shí)的功能與javascript
里的事件是相似的,都是通過用戶點(diǎn)擊元素觸發(fā)定義在元素上的事件。Ember的action助手還允許你傳遞參數(shù)到對應(yīng)的controller
、component
類,在controller
或者component
上處理事件的邏輯。
準(zhǔn)備工作,我們使用Ember CLI命令創(chuàng)建一個(gè)名稱為myaction
的controller
和同名的route
,如果你不知道怎么使用Ember CLI請看前面的文章Ember.js 入門指南之七第一章對象模型小結(jié),這篇文件講解了怎么使用Ember CLI構(gòu)建一個(gè)簡單的Ember項(xiàng)目。
// apap/routes/myaction.js
import Ember from 'ember';
export default Ember.Route.extend({
// 返回測試數(shù)據(jù)到頁面
model: function() {
return { id:1, title: 'ACTIONS', body: "Your app will often need a way to let users interact with controls that change application state. For example, imagine that you have a template that shows a blog title, and supports expanding the post to show the body.If you add the {{action}} helper to an HTML element, when a user clicks the element, the named event will be sent to the template's corresponding component or controller." };
}
});
重寫model
回調(diào),直接返回一個(gè)對象數(shù)據(jù)。
<h2 {{action ' showDetailInfo '}} style="cursor: pointer;">{{model.title}}</h2>
{{#if isShowingBody}}
<p>
{{model.body}}
</p>
{{/if}}
默認(rèn)下只顯示文章的標(biāo)題,當(dāng)用戶點(diǎn)擊標(biāo)題的時(shí)候觸發(fā)事件toggleBody
顯示文章的詳細(xì)信息。
// app/controllers/myaction.js
import Ember from 'ember';
export default Ember.Controller.extend({
// 控制頁面文章詳細(xì)內(nèi)容是否顯示
isShowingBody: false,
actions: {
showDetailInfo: function() {
// toggleProperty方法直接把isShowingBody設(shè)置為相反值
// toggleProperty方法詳情:http://devdocs.io/ember/classes/ember.observable#method_toggleProperty
this.toggleProperty('isShowingBody');
}
}
});
對于controller
的處理邏輯你還可以直接編寫觸發(fā)的判斷。
actions: {
showDetailInfo: function() {
// toggleProperty方法直接把isShowingBody設(shè)置為相反值
// toggleProperty方法詳情:http://devdocs.io/ember/classes/ember.observable#method_toggleProperty
// this.toggleProperty('isShowingBody');
// 變量作用域問題
var isShowingBody = this.get('isShowingBody');
if (isShowingBody) {
this.set('isShowingBody', false);
} else {
this.set('isShowingBody', true);
}
}
}
如果你不使用toggleProperty
方法改變isShowingBody
的值,你也可用直接編寫代碼修改它的值。
最后執(zhí)行URL:http://localhost:4200/myaction,默認(rèn)情況下頁面上是不顯示文章的詳細(xì)信息的,當(dāng)你點(diǎn)擊標(biāo)題則會觸發(fā)事件,顯示詳細(xì)信息,下面2個(gè)圖片分別展示的是默認(rèn)情況和點(diǎn)擊標(biāo)題之后。當(dāng)我們再次點(diǎn)擊標(biāo)題,詳細(xì)內(nèi)容又變?yōu)殡[藏。
通過上述的小例子可以看到action
助手使用起來也是非常簡單的。主要注意下模板上的action
所指定的事件名稱要與controller
里的方法名字一致。
就像調(diào)用javascript
的方法一樣,你也可以為action
助手增加必要的參數(shù)。只要在action
名字后面接上你的參數(shù)即可。
<p>
<button {{action 'hitMe' model}}>點(diǎn)擊我吧</button>
</p>
對應(yīng)的在controller
增加處理的方法selected
。在此方法內(nèi)打印獲取到的參數(shù)值。
// app/controllers/myaction.js
import Ember from 'ember';
export default Ember.Controller.extend({
// 控制頁面文章詳細(xì)內(nèi)容是否顯示
isShowingBody: false,
actions: {
showDetailInfo: function() {
// ……同上面的例子
},
hitMe: function(model) { // 參數(shù)的名字可以任意
console.log('The title is ' + model.title);
console.log('The body is ' + model.body);
}
}
});
Ember規(guī)定我們編寫的動作處理的方法都是放在actions
這個(gè)哈希內(nèi)。哈希的鍵就是方法名。在controller
方法上的參數(shù)名不要求與模板上傳遞的名字一致,你可以任意定義。比如方法hitMe
的參數(shù)model
你也可以使用m
作為hitMe
方法的參數(shù)。
當(dāng)用戶點(diǎn)擊按鈕“點(diǎn)擊我吧”就會觸發(fā)方法hitMe
,然后執(zhí)行controller
的同名方法,最后你可以在瀏覽器的console
下看到如下的打印信息。
看到這些打印結(jié)果很好的說明了獲取的參數(shù)是正確的。
默認(rèn)情況下action
觸發(fā)的是click
事件,你可以指定其他事件,比如鍵盤按下事件keypress
。事件的名字與javascript
提供的名字是相似的,唯一不同的是Ember所識別是事件名字如果是由不同單詞組成的需要用中劃線分隔,比如keypress
事件在Ember模板中你需要寫成key-press
。
注意:你指定事件的時(shí)候要把事件的名字作為on
的屬性。比如on='key-press'
。
<a href="#/myaction" {{action 'triggerMe' on="mouse-over"}}>鼠標(biāo)移到我身上觸發(fā)</a>
triggerMe: function() {
console.log('觸發(fā)mouseover事件。。。。');
}
action
觸發(fā)事件的輔助按鍵
甚至你還可以指定按下鍵盤某個(gè)鍵后點(diǎn)擊才觸發(fā)action
所指定的事件,比如按下鍵盤的Alt
再點(diǎn)擊才會觸發(fā)事件。使用allowedkeys
屬性指定按下的是那個(gè)鍵。
<br><br>
<button {{action 'pressALTKeyTiggerMe' allowedkeys='alt'}}>按下Alt點(diǎn)擊觸發(fā)我</button>
在action
助手內(nèi)使用屬性preventDefault=false
可以禁止標(biāo)簽的默認(rèn)行為,比如下面的a標(biāo)簽,如果action
助手內(nèi)沒有定義這個(gè)屬性那么你點(diǎn)擊鏈接時(shí)只會執(zhí)行執(zhí)行的action
動作,a
標(biāo)簽?zāi)J(rèn)的行為不會被觸發(fā)。
<a rel="external nofollow" target="_blank" target="_blank" {{action "showDetailInfo" preventDefault=false}}>
點(diǎn)我跳轉(zhuǎn)
</a>
controller
handlebars
的action
助手真的是非常強(qiáng)大,你甚至可以把觸發(fā)的事件作為action
的參數(shù)直接傳遞到controller
。不過你需要把action
助手放在javascript
的事件里。比如下面的代碼當(dāng)失去焦點(diǎn)時(shí)觸發(fā),并且通過action
指定的dandDidChange
把觸發(fā)的事件blur
傳遞到controller
。
失去焦點(diǎn)時(shí)候觸發(fā)
<input type="text" value={{textValue}} onblur={{action 'bandDidChange'}} />
// app/controllers/myaction.js
import Ember from 'ember';
export default Ember.Controller.extend({
actions: {
bandDidChange: function(event) {
console.log('event = ' + event);
}
}
});
從控制臺輸出結(jié)果看出來event
的值是一個(gè)對象并且是一個(gè)focus
事件。
但是如果你在action
助手內(nèi)增加一個(gè)屬性value='target.value'
(別寫錯只能是target.value
)之后,傳遞到controller
的則是輸入框本身的內(nèi)容。不再是事件對象本身。
<input type="text" value={{textValue}} onblur={{action 'bandDidChange' value="target.value"}} />
這個(gè)比較有意思,實(shí)現(xiàn)的功能與前面的參數(shù)傳遞類似的。
action
助手用在非點(diǎn)擊元素上`action`助手可以用在任何的`DOM`元素上,不僅僅是用在能點(diǎn)擊的元素上(比如`a`、`button`),但是用在其他非點(diǎn)擊的元素上默認(rèn)情況下是不可用的,也就是說點(diǎn)擊也是無效的。比如用在`div`標(biāo)簽上,但是你點(diǎn)擊`div`元素是沒有反應(yīng)的。如果你需要讓`div`元素也能觸發(fā)單擊事件你需要給元素添加一個(gè)CSS類'cursor:pointer;`。
總的來說Ember的action
助手與普通的javascript的事件是差不多的。用法基本上與javascript的事件相似。
博文完整代碼放在Github(博文經(jīng)過多次修改,博文上的代碼與github代碼可能又出入,不過影響不大?。绻阌X得博文對你有點(diǎn)用,請?jiān)趃ithub項(xiàng)目上給我點(diǎn)個(gè)star
吧。您的肯定對我來說是最大的動力??!
更多建議: