Ember 組件定義

2018-01-06 17:52 更新

不得不說,Ember的更新是在是太快了!!本教程還沒寫到一半就又更新到v2.1.0了?。。?!不過為了統(tǒng)一還是使用官方v2.0.0的參考文檔!!

從本篇開始進入新的一章——組件。這一章將用6篇文章介紹Ember的組件,從它的定義開始知道它的使用方式,我將為你一一解答!

準(zhǔn)備工作: 本章代碼統(tǒng)一訪問項目chapter4_components下,項目代碼可以在以下網(wǎng)址上找到: https://github.com/ubuntuvim/my_emberjs_code

與之前的文章一樣,項目仍然是使用Ember CLI命令創(chuàng)建項目和各個組件文件。

創(chuàng)建項目并測試運行,首先執(zhí)行如下四條命令,最后在瀏覽器執(zhí)行:http://localhost:4200/。

ember new chapter4_components
cd chapter4_components
ember server

如果你能在頁面上看到Welcome to Ember說明項目框架搭建成功!那么你可以繼續(xù)往下看了,否則想搭建好項目再往下學(xué)習(xí)~~~

1,自定義組件及使用

創(chuàng)建組件方法很簡單:ember generate component my-component-name。一條命令即可,但是需要注意的是組件的名稱必須要包含中劃線-,比如blog-post、test-componentaudio-player-controls這種格式的命名是合法,但是post、test這種方式的命名是不合法的!其一是為了防止用戶自定義的組件名與W3C規(guī)定的元素標(biāo)簽名重復(fù);其二是為了確保Ember能自動檢測到用戶自定義的組件。

下面定義一個組件,ember g component blog-post。Ember CLI會自動為你創(chuàng)建組件對應(yīng)的的模板,執(zhí)行這條命令之后你可以在app/componentsapp/templates/components下看到創(chuàng)建的文件。







    <h2>{{title}}</h2>
    <p>{{yield}}</p>
    <p>Edit title: {{input type="text" value=title}}</p>

為了演示組件的使用需要做些準(zhǔn)備工作: ember g route index

//  app/routes/index.js


import Ember from 'ember';


export default Ember.Route.extend({

    
    model: function() {
         return [
            { id: 1, title: 'Bower: dependencies and resolutions new', body: "In the bower.json file, I see 2 keys dependencies and resolutionsWhy is that so? I understand Bower has a flat dependency structure. So has it got anything to do with that ?", category: 'java' },
            { id: 2, title: 'Highly Nested JSON Payload - hasMany error', body: "Welcome to the Ember.js discussion forum. We're running on the open source, Ember.js-powered Discourse forum software. They are also providing the hosting for us. Thanks guys! Please use this space for discussion abo… read more", category: 'php' },
            { id: 3, title: 'Passing a jwt to my REST adapter new ', body: "This sets up a binding between the category query param in the URL, and the category property on controller:articles. In other words, once the articles route has been entered, any changes to the category query param in the URL will update the category property on controller:articles, and vice versa.", category: 'java'}
        ];

       
    }
});




{{#each model as |item|}}

    
    {{#blog-post title=item.title}}
        {{item.body}}
    {{/blog-post}}
{{/each}}

在這段代碼中,使用了自定義的組件來顯示數(shù)據(jù)。最后頁面顯示如下:

運行結(jié)果截圖

渲染后的HTML代碼

自定義的組件被渲染到了模板index.hbs使用blog-post的地方。并且自定義組件的HTML標(biāo)簽沒有變化。 到這里大概應(yīng)該知道怎么去使用組件了,至于它是怎么就渲染到了使用組件的地方,以及它是怎么渲染上去的。別急~~后面的文章會為你一一解答。

說明:默認情況下,自定義的組件會被渲染到div標(biāo)簽內(nèi),當(dāng)然這種默認情況也是可以修改的,比較簡單在此不過多介紹,請自行學(xué)習(xí),網(wǎng)址:customizing-a-components-element。

2,自定義組件類

用戶自定義的組件類都需要繼承Ember.Component類。

通常情況下我們會把經(jīng)常使用的模板片段封裝成組件,只需要定義一次就可以在項目任何一個模板中使用,而且不需要編寫任何的javascript代碼。比如上述第一點“自定義組件及使用”中描述的一樣。

但是如果你想你的組件有特殊的行為,并且這些行為是默認組件類無法提供的(比如:改變包裹組件的標(biāo)簽、響應(yīng)組件模板初始化某個狀態(tài)等),那么此時你可以自定義組件類,但是要繼承Ember.Component,如果你自定義的組件類沒有繼承這個類,你自定義的組件就很有可能會出現(xiàn)一些不可預(yù)知的問題。

Ember所能識別的自定義組件類的名稱是有規(guī)范的。比如,你定義了一個名為blog-post的組件,那么你的組件類的名稱應(yīng)該是app/components/blog-post.js。如果組件名為audio-player-controls那么對應(yīng)的組件類名為app/components/audio-player-controls.js。即:組件類名與組件同名,這個是v2.0的命名方法,請區(qū)別就版本的Ember,舊版本的組件命名規(guī)則是駝峰式的命名規(guī)則。

舉個簡單的例子,在第一點“自定義組件及使用”中講過,組件默認會被渲染到div標(biāo)簽內(nèi),你可以在組件類中修改這個默認標(biāo)簽。

//  app/components/blog-post.js


import Ember from 'ember';


export default Ember.Component.extend({
    tagName: 'nav'
});

這段代碼修改了包裹組件的標(biāo)簽名,頁面刷新后HTML代碼如下:

渲染后的HTML代碼

可以看到組件的HTML代碼被包含在nav標(biāo)簽內(nèi)。

3,動態(tài)渲染組件

組件的動態(tài)渲染與Java的多態(tài)有點相似。{{component}}助手會延遲到運行時才決定使用那個組件渲染頁面。當(dāng)程序需要根據(jù)數(shù)據(jù)不同渲染不同組件的時,這種動態(tài)渲染就顯得特別有用??梢允鼓愕倪壿嫼驮噲D分離開。

那么要怎么使用呢?非常簡單,只需要把組件名作為參數(shù)傳遞過去即可,比如:使用{{component 'blog-post'}}{{blog-post}}結(jié)果是一致的。我們可以修改第一點“自定義組件及使用”實例中模板index.hbs的代碼。





{{#each model as |item|}}

    
    {{component 'blog-post' title=item.title}}
    {{item.body}}
{{/each}}

頁面刷新之后,可以看到結(jié)果是一樣的。

下面為讀者演示如何根據(jù)數(shù)據(jù)不同渲染不同的組件。

按照慣例,先做好準(zhǔn)備工作,使用Ember CLI命令創(chuàng)建2個不同的組件。

ember g component foo-component
ember g component bar-component




<h2>Hello from bar</h2>
<p>{{post.body}}</p>

為何能用post獲取數(shù)據(jù),因為在使用組件的地方傳遞了參數(shù)。在模板index.hbs中可以看到。





<h2>Hello from foo</h2>
<p>{{post.body}}</p>

修改顯示的數(shù)據(jù),注意數(shù)據(jù)的最后增加一個屬性pn,pn的值就是組件的名稱。

//  app/routes/index.js


import Ember from 'ember';


export default Ember.Route.extend({


    model: function() {
         return [
            { id: 1, title: 'Bower: dependencies and resolutions new', body: "In the bower.json file, I see 2 keys dependencies and resolutionsWhy is that so? I understand Bower has a flat dependency structure. So has it got anything to do with that ?", pn: 'bar-component' },
            { id: 2, title: 'Highly Nested JSON Payload - hasMany error', body: "Welcome to the Ember.js discussion forum. We're running on the open source, Ember.js-powered Discourse forum software. They are also providing the hosting for us. Thanks guys! Please use this space for discussion abo… read more", pn: 'foo-component' },
            { id: 3, title: 'Passing a jwt to my REST adapter new ', body: "This sets up a binding between the category query param in the URL, and the category property on controller:articles. In other words, once the articles route has been entered, any changes to the category query param in the URL will update the category property on controller:articles, and vice versa.", pn: 'bar-component'}
        ];

       
    }
});

修改調(diào)用組件的模板index.hbs。





{{#each model as |item|}}

    
    {{component item.pn post=item}}
{{/each}}

模板編譯之后會得到形如{{component foo-component post}}的組件調(diào)用代碼。

相信你應(yīng)該了解了動態(tài)渲染組件是怎么回事了!自己動手試試吧~~

到此組件的定義與使用介紹完畢了,不知道你有沒有學(xué)會呢?如果你有疑問請給我留言或者直接看官方教程學(xué)習(xí)。


博文完整代碼放在Github(博文經(jīng)過多次修改,博文上的代碼與github代碼可能有出入,不過影響不大?。?,如果你覺得博文對你有點用,請在github項目上給我點個star吧。您的肯定對 我來說是最大的動力!!

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

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號