Ember.js 入門指南——{{action}} 助手
action助手所現實的功能與javascript裡的事件是相似的,都是通過使用者點選元素觸發定義在元素上的事件。Ember的action助手還允許你傳遞引數到對應的controller、component類,在controller或者component上處理事件的邏輯。
準備工作,我們使用Ember CLI命令建立一個名稱為myaction的controller和同名的route,如果你不知道怎麼使用Ember CLI請看前面的文章《Ember.js 入門指南——handlebars基礎
》,這篇檔案講解了怎麼使用Ember CLI構建一個簡單的Ember專案。
1,action使用例項
1,在route層增加測試資料
// app/routes/myaction.js import Ember from 'ember'; export default Ember.Route.extend({ // 返回測試資料到頁面 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回撥,直接返回一個物件資料。
2,編寫action模板
<!-- // app/templates/myaction.hbs --> <!-- showDetailInfo這個事件的名字必須要跟controller裡的方法名字一致 --> <h2 {{action ' showDetailInfo '}} style="cursor: pointer;">{{model.title}}</h2> {{#if isShowingBody}} <p> {{model.body}} </p> {{/if}}
預設下只顯示文章的標題,當用戶點選標題的時候觸發事件“toggleBody”顯示文章的詳細資訊。
3,編寫action的controller實現模板所需要的邏輯
// app/controllers/myaction.js import Ember from 'ember'; export default Ember.Controller.extend({ // 控制頁面文章詳細內容是否顯示 isShowingBody: false, actions: { showDetailInfo: function() { // toggleProperty方法直接把isShowingBody設定為相反值 // toggleProperty方法詳情:http://devdocs.io/ember/classes/ember.observable#method_toggleProperty this.toggleProperty('isShowingBody'); } } });
對於controller的處理邏輯你還可以直接編寫觸發的判斷。
actions: { showDetailInfo: function() { // toggleProperty方法直接把isShowingBody設定為相反值 // 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的值,你也可用直接編寫程式碼修改它的值。
最後執行URL:http://localhost:4200/myaction,預設情況下頁面上是不顯示文章的詳細資訊的,當你點選標題則會觸發事件,顯示詳細資訊,下面2個圖片分別展示的是預設情況和點選標題之後。當我們再次點選標題,詳細內容又變為隱藏。
通過上述的小例子可以看到action助手使用起來也是非常簡單的。主要注意下模板上的action所指定的事件名稱要與controller裡的方法名字一致。
2,action引數
就像呼叫javascript的方法一樣,你也可以為action助手增加必要的引數。只要在action名字後面接上你的引數即可。
<p>
<!-- model直接作為引數傳遞到controller -->
<button {{action 'hitMe' model}}>點選我吧</button>
</p>
對應的在controller增加處理的方法selected。在此方法內列印獲取到的引數值。
// app/controllers/myaction.js import Ember from 'ember'; export default Ember.Controller.extend({ // 控制頁面文章詳細內容是否顯示 isShowingBody: false, actions: { showDetailInfo: function() { // ……同上面的例子 }, hitMe: function(model) { // 引數的名字可以任意 console.log('The title is ' + model.title); console.log('The body is ' + model.body); } } });
Ember規定我們編寫的動作處理的方法都是放在actions這個雜湊內。雜湊的鍵就是方法名。在controller方法上的引數名不要求與模板上傳遞的名字一致,你可以任意定義。比如方法hitMe的引數” model”你也可以使用”m”作為hitMe方法的引數。
當用戶點選按鈕“點選我吧”就會觸發方法hitMe,然後執行controller的同名方法,最後你可以在瀏覽器的console下看到如下的列印資訊。
看到這些列印結果很好的說明了獲取的引數是正確的。
3,指定action觸發的事件型別
預設情況下action觸發的是click事件,你可以指定其他事件,比如鍵盤按下事件keypress。事件的名字與javascript提供的名字是相似的,唯一不同的是Ember所識別是事件名字如果是由不同單片語成的需要用中劃線分隔,比如kekpress事件在Ember模板中你需要寫成key-press。
注意:你指定事件的時候要把事件的名字作為on的屬性。比如on=”key-press”。
<a href="#/myaction" {{action 'triggerMe' on="mouse-over"}}>滑鼠移到我身上觸發</a>
triggerMe: function() { console.log('觸發mouseover事件。。。。'); }
4,指定action觸發事件的輔助按鍵
甚至你還可以指定按下鍵盤某個鍵後點擊才觸發action所指定的事件,比如按下鍵盤的Alt再點選才會觸發事件。使用allowedkeys屬性指定按下的是那個鍵。
<button {{action 'pressALTKeyTiggerMe' allowedkeys='alt'}}>按下Alt點選觸發我</button>
5,設定連結為不可用
在action助手內使用屬性“preventDefault=false”可以設定連結是否可用,比如下面的a標籤,如果action助手內沒有定義這個屬性那麼你點選連結時不會跳轉。
<a href="http://www.baidu.com" {{action "showDetailInfo" preventDefault=false}}>
點我跳轉
</a>
6,可以把觸發的事件作為引數傳遞到controller
handlebars的action助手真的是非常強大,你甚至可以把觸發的事件作為action的引數直接傳遞到controller。不過你需要把action助手放在javascript的事件裡。比如下面的程式碼當失去焦點時觸發,並且通過action指定的dandDidChange把觸發的事件blur傳遞到controller。
<label>失去焦點時候觸發</label>
<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);
}
}
});
從控制檯輸出結果看出來event的值是一個物件並且是一個focus事件。
但是如果你在action助手內增加一個屬性value=“target.value”(別寫錯只能是target.value)之後,傳遞到controller的則是輸入框本身的內容。不再是事件物件本身。
<input type="text" value={{textValue}} onblur={{action 'bandDidChange' value="target.value"}} />
這個比較有意思,實現的功能與前面的引數傳遞類似的。
總的來說Ember的action助手與普通的javascript的事件是差不多的。用法基本上與javascript的事件相似。
action助手可以用在所有的DOM元素上!