Ember {{action}} 助手

2018-01-06 17:40 更新

action助手所現(xiàn)實(shí)的功能與javascript里的事件是相似的,都是通過用戶點(diǎn)擊元素觸發(fā)定義在元素上的事件。Ember的action助手還允許你傳遞參數(shù)到對應(yīng)的controller、component類,在controller或者component上處理事件的邏輯。 準(zhǔn)備工作,我們使用Ember CLI命令創(chuàng)建一個(gè)名稱為myactioncontroller和同名的route,如果你不知道怎么使用Ember CLI請看前面的文章Ember.js 入門指南之七第一章對象模型小結(jié),這篇文件講解了怎么使用Ember CLI構(gòu)建一個(gè)簡單的Ember項(xiàng)目。

1,action使用實(shí)例

1,在route層增加測試數(shù)據(jù)

//  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ù)。

2,編寫action模板







<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ì)信息。

3,編寫action的controller實(shí)現(xiàn)模板所需要的邏輯

// 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)殡[藏。

圖片1

圖片2

通過上述的小例子可以看到action助手使用起來也是非常簡單的。主要注意下模板上的action所指定的事件名稱要與controller里的方法名字一致。

2,action參數(shù)

就像調(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下看到如下的打印信息。

run result

看到這些打印結(jié)果很好的說明了獲取的參數(shù)是正確的。

3,指定action觸發(fā)的事件類型

默認(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事件。。。。');
}

4,指定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>

5,禁止標(biāo)簽?zāi)J(rèn)行為

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>

6,可以把觸發(fā)的事件作為參數(shù)傳遞到controller

handlebarsaction助手真的是非常強(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);
        }
    }

    
});

result

從控制臺輸出結(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"}} />

result

這個(gè)比較有意思,實(shí)現(xiàn)的功能與前面的參數(shù)傳遞類似的。

7,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吧。您的肯定對我來說是最大的動力??!

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號