Ember {{action}} 助手

2018-01-06 17:40 更新

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è)名稱為myactioncontroller和同名的route,如果你不知道怎么使用Ember CLI請(qǐng)看前面的文章Ember.js 入門(mén)指南之七第一章對(duì)象模型小結(jié),這篇文件講解了怎么使用Ember CLI構(gòu)建一個(gè)簡(jiǎn)單的Ember項(xiàng)目。

1,action使用實(shí)例

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

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

2,編寫(xiě)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,編寫(xiě)action的controller實(shí)現(xiàn)模板所需要的邏輯

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

圖片1

圖片2

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

2,action參數(shù)

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

run result

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

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

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

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

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

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>

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

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

    
});

result

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

result

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

7,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)力??!

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

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)