action
助手所現(xiàn)實(shí)的功能與javascript
里的事件是相似的,都是通過(guò)用戶點(diǎn)擊元素觸發(fā)定義在元素上的事件。Ember的action助手還允許你傳遞參數(shù)到對(duì)應(yīng)的controller
、component
類,在controller
或者component
上處理事件的邏輯。
準(zhǔn)備工作,我們使用Ember CLI命令創(chuàng)建一個(gè)名稱為myaction
的controller
和同名的route
,如果你不知道怎么使用Ember CLI請(qǐng)看前面的文章Ember.js 入門(mén)指南之七第一章對(duì)象模型小結(jié),這篇文件講解了怎么使用Ember CLI構(gòu)建一個(gè)簡(jiǎn)單的Ember項(xiàng)目。
// apap/routes/myaction.js
import Ember from 'ember';
export default Ember.Route.extend({
// 返回測(cè)試數(shù)據(jù)到頁(yè)面
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." };
}
});
重寫(xiě)model
回調(diào),直接返回一個(gè)對(duì)象數(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({
// 控制頁(yè)面文章詳細(xì)內(nèi)容是否顯示
isShowingBody: false,
actions: {
showDetailInfo: function() {
// toggleProperty方法直接把isShowingBody設(shè)置為相反值
// toggleProperty方法詳情:http://devdocs.io/ember/classes/ember.observable#method_toggleProperty
this.toggleProperty('isShowingBody');
}
}
});
對(duì)于controller
的處理邏輯你還可以直接編寫(xiě)觸發(fā)的判斷。
actions: {
showDetailInfo: function() {
// toggleProperty方法直接把isShowingBody設(shè)置為相反值
// toggleProperty方法詳情:http://devdocs.io/ember/classes/ember.observable#method_toggleProperty
// this.toggleProperty('isShowingBody');
// 變量作用域問(wèn)題
var isShowingBody = this.get('isShowingBody');
if (isShowingBody) {
this.set('isShowingBody', false);
} else {
this.set('isShowingBody', true);
}
}
}
如果你不使用toggleProperty
方法改變isShowingBody
的值,你也可用直接編寫(xiě)代碼修改它的值。
最后執(zhí)行URL:http://localhost:4200/myaction,默認(rèn)情況下頁(yè)面上是不顯示文章的詳細(xì)信息的,當(dāng)你點(diǎn)擊標(biāo)題則會(huì)觸發(fā)事件,顯示詳細(xì)信息,下面2個(gè)圖片分別展示的是默認(rèn)情況和點(diǎn)擊標(biāo)題之后。當(dāng)我們?cè)俅吸c(diǎn)擊標(biāo)題,詳細(xì)內(nèi)容又變?yōu)殡[藏。
通過(guò)上述的小例子可以看到action
助手使用起來(lái)也是非常簡(jiǎn)單的。主要注意下模板上的action
所指定的事件名稱要與controller
里的方法名字一致。
就像調(diào)用javascript
的方法一樣,你也可以為action
助手增加必要的參數(shù)。只要在action
名字后面接上你的參數(shù)即可。
<p>
<button {{action 'hitMe' model}}>點(diǎn)擊我吧</button>
</p>
對(duì)應(yīng)的在controller
增加處理的方法selected
。在此方法內(nèi)打印獲取到的參數(shù)值。
// app/controllers/myaction.js
import Ember from 'ember';
export default Ember.Controller.extend({
// 控制頁(yè)面文章詳細(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ī)定我們編寫(xiě)的動(dòng)作處理的方法都是放在actions
這個(gè)哈希內(nèi)。哈希的鍵就是方法名。在controller
方法上的參數(shù)名不要求與模板上傳遞的名字一致,你可以任意定義。比如方法hitMe
的參數(shù)model
你也可以使用m
作為hitMe
方法的參數(shù)。
當(dāng)用戶點(diǎn)擊按鈕“點(diǎn)擊我吧”就會(huì)觸發(fā)方法hitMe
,然后執(zhí)行controller
的同名方法,最后你可以在瀏覽器的console
下看到如下的打印信息。
看到這些打印結(jié)果很好的說(shuō)明了獲取的參數(shù)是正確的。
默認(rèn)情況下action
觸發(fā)的是click
事件,你可以指定其他事件,比如鍵盤(pán)按下事件keypress
。事件的名字與javascript
提供的名字是相似的,唯一不同的是Ember所識(shí)別是事件名字如果是由不同單詞組成的需要用中劃線分隔,比如keypress
事件在Ember模板中你需要寫(xiě)成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ā)事件的輔助按鍵
甚至你還可以指定按下鍵盤(pán)某個(gè)鍵后點(diǎn)擊才觸發(fā)action
所指定的事件,比如按下鍵盤(pán)的Alt
再點(diǎn)擊才會(huì)觸發(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)沒(méi)有定義這個(gè)屬性那么你點(diǎn)擊鏈接時(shí)只會(huì)執(zhí)行執(zhí)行的action
動(dòng)作,a
標(biāo)簽?zāi)J(rèn)的行為不會(huì)被觸發(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
。不過(guò)你需要把action
助手放在javascript
的事件里。比如下面的代碼當(dāng)失去焦點(diǎn)時(shí)觸發(fā),并且通過(guò)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);
}
}
});
從控制臺(tái)輸出結(jié)果看出來(lái)event
的值是一個(gè)對(duì)象并且是一個(gè)focus
事件。
但是如果你在action
助手內(nèi)增加一個(gè)屬性value='target.value'
(別寫(xiě)錯(cuò)只能是target.value
)之后,傳遞到controller
的則是輸入框本身的內(nèi)容。不再是事件對(duì)象本身。
<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)情況下是不可用的,也就是說(shuō)點(diǎn)擊也是無(wú)效的。比如用在`div`標(biāo)簽上,但是你點(diǎn)擊`div`元素是沒(méi)有反應(yīng)的。如果你需要讓`div`元素也能觸發(fā)單擊事件你需要給元素添加一個(gè)CSS類'cursor:pointer;`。
總的來(lái)說(shuō)Ember的action
助手與普通的javascript的事件是差不多的。用法基本上與javascript的事件相似。
博文完整代碼放在Github(博文經(jīng)過(guò)多次修改,博文上的代碼與github代碼可能又出入,不過(guò)影響不大?。?,如果你覺(jué)得博文對(duì)你有點(diǎn)用,請(qǐng)?jiān)趃ithub項(xiàng)目上給我點(diǎn)個(gè)star
吧。您的肯定對(duì)我來(lái)說(shuō)是最大的動(dòng)力??!
更多建議: