按照慣例,先做好準(zhǔn)備工作,使用Ember CLI命令生成演示所需的文件:
ember g route customizing-component-element
ember g component customizing-component-element
ember g route home
ember g route about
默認(rèn)情況下,組件會被包裹在div
標(biāo)簽內(nèi)。比如,組件渲染之后得到下面的代碼:
<div id="ember180" class="ember-view">
<h2>My Component</h2>
</div>
h1
標(biāo)簽就是組件的內(nèi)容。以ember
開頭的id
和class
都是Ember自動生成的。如果你需要修改渲染之后生成的HTML不是被包裹在div
標(biāo)簽,或者修改id
和class
等屬性值為自定義的值,你可以在組件類中設(shè)置。
默認(rèn)情況下,組件會被包裹在div
標(biāo)簽內(nèi),如果你需要修改這個默認(rèn)值你可以在組件類中指定這個包裹的HTML標(biāo)簽。
// app/components/customizing-component-element.js
import Ember from 'ember';
export default Ember.Component.extend({
// 使用tabName屬性指定渲染之后HTML標(biāo)簽
// 注意屬性的值必須是標(biāo)準(zhǔn)的HTML標(biāo)簽名
tagName: 'nav'
});
下面自定義一個組件。
<ul>
<li>{{#link-to 'home'}}Home{{/link-to}}</li>
<li>{{#link-to 'about'}}About{{/link-to}}</li>
</ul>
下面是調(diào)用組件的模板代碼。注意組件被包裹在那個HTML標(biāo)簽內(nèi),正確情況下應(yīng)該是被包裹在nav
標(biāo)簽中。
{{customizing-component-element}}
頁面加載之后查看頁面的源代碼。如下:
可以看到組件customizing-component-element
的內(nèi)容確實是被包裹在nav
標(biāo)簽之中,如果在組件類中沒有使用屬性tagName
指定包裹的HTML標(biāo)簽,默認(rèn)是div
,你可以把組件類中tagName
屬性刪除之后再查看頁面的HTML源碼代碼。
默認(rèn)情況下,Ember會自動為包裹組件的HTML元素增加一個以ember
開頭的類名,如果你需要增加自定義的CSS類,可以在組件類中使用className
數(shù)組屬性指定,可以一次性指定多個CSS類。比如下面的代碼例子:
// app/components/customizing-component-element.js
import Ember from 'ember';
export default Ember.Component.extend({
// 使用tabName屬性指定渲染之后HTML標(biāo)簽
// 注意屬性的值必須是標(biāo)準(zhǔn)的HTML標(biāo)簽名
tagName: 'nav',
classNames: ['primary', 'my-class-name'] //指定包裹元素的CSS類
});
頁面重新加載之后查看源代碼,可以看到nav
標(biāo)簽中多了兩個CSS類,一個是primary
,一個是my-class-name
。
……
如果你想根據(jù)某個數(shù)據(jù)的值決定是否增加CSS類也是可以做到的,比如下面的代碼,當(dāng)urgent
為true
的時增加一個CSS類urgent
,否則不增加這個類。要達(dá)到這個目的可以通過屬性classNameBindings
設(shè)置。
// app/components/customizing-component-element.js
import Ember from 'ember';
export default Ember.Component.extend({
// 使用tabName屬性指定渲染之后HTML標(biāo)簽
// 注意屬性的值必須是標(biāo)準(zhǔn)的HTML標(biāo)簽名
tagName: 'nav',
classNames: ['primary', 'my-class-name'], //指定包裹元素的CSS類
classNameBindings: ['urgent'],
urgent: true
});
頁面重新加載之后查看源代碼,可以看到nav
標(biāo)簽中多了一個CSS類urgent
,如果屬性urgent
的值為false
,CSS類urgent
將不會渲染到nav
標(biāo)簽上。
……
注意:classNameBindings
指定的屬性值必須要跟用于判斷數(shù)據(jù)的屬性名一致,比如這個例子中classNameBindings
指定的屬性值是urgent
,用戶判斷是否增加類的屬性也是urgent
。如果這個屬性只是駝峰式命名的那么渲染之后CSS類名將是以中劃線-
分隔,比如classNameBindings
指定一個名為secondClassName
,渲染后的CSS類為second-class-name
。比如下面的演示代碼:
// app/components/customizing-component-element.js
import Ember from 'ember';
export default Ember.Component.extend({
// 使用tabName屬性指定渲染之后HTML標(biāo)簽
// 注意屬性的值必須是標(biāo)準(zhǔn)的HTML標(biāo)簽名
tagName: 'nav',
classNames: ['primary', 'my-class-name'], //指定包裹元素的CSS類
classNameBindings: ['urgent', 'secondClassName'],
urgent: true,
secondClassName: true
});
頁面重新加載之后查看源代碼,可以看到nav
標(biāo)簽中多了一個CSS類second-class-name
。
……
如果你不想渲染之后的CSS類名被修改為中劃線分隔形式,你可以值classNameBindings
屬性中指定渲染之后的CSS類名。比如下面的代碼:
// app/components/customizing-component-element.js
import Ember from 'ember';
export default Ember.Component.extend({
// 使用tabName屬性指定渲染之后HTML標(biāo)簽
// 注意屬性的值必須是標(biāo)準(zhǔn)的HTML標(biāo)簽名
tagName: 'nav',
classNames: ['primary', 'my-class-name'], //指定包裹元素的CSS類
classNameBindings: ['urgent', 'secondClassName:scn'], //指定secondClassName渲染之后的CSS類名為scn
urgent: true,
secondClassName: true
});
頁面重新加載之后查看源代碼,可以看到nav
標(biāo)簽中原來CSS類為second-class-name
的變成了scn
。
……
有沒有感覺Ember既靈活又強大?。?a rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" >Ember的設(shè)計理念是“約定優(yōu)于配置”!所以很多的屬性默認(rèn)的設(shè)置都是我們平常開發(fā)中最常用的格式。
除了上述可以指定CSS類名之外,還可以在classNameBindings
增加簡單的邏輯,特別是在處理一些動態(tài)效果的時候上述特性是非常有用的。
// app/components/customizing-component-element.js
import Ember from 'ember';
export default Ember.Component.extend({
// 使用tabName屬性指定渲染之后HTML標(biāo)簽
// 注意屬性的值必須是標(biāo)準(zhǔn)的HTML標(biāo)簽名
tagName: 'nav',
classNames: ['primary', 'my-class-name'], //指定包裹元素的CSS類
classNameBindings: ['urgent', 'secondClassName:scn', 'isEnabled:enabled:disabled'],
urgent: true,
secondClassName: true,
isEnabled: true //如果這個屬性為true,類enabled將被渲染到nav標(biāo)簽上,如果屬性值為false類disabled將被渲染到nav標(biāo)簽上,類似于三目運算
});
正如代碼的注釋所說的,isEnabled:enabled:disabled
可以理解為一個三目運算,會根據(jù)isEnabled
的值渲染不同的CSS類到nav
上。
下面的HTML代碼是isEnabled
為true
的情況,對于isEnabled
為false
的情況請讀者自己試試:
……
注意:如果用于判斷的屬性值不是一個Boolean
值而是一個字符串那么得到的結(jié)果與上面的結(jié)果是不一樣的,Ember會直接把這個字符串的值作為CSS類名渲染到包裹的標(biāo)簽上。比如下面的代碼:
// app/components/customizing-component-element.js
import Ember from 'ember';
export default Ember.Component.extend({
// 使用tabName屬性指定渲染之后HTML標(biāo)簽
// 注意屬性的值必須是標(biāo)準(zhǔn)的HTML標(biāo)簽名
tagName: 'nav',
classNames: ['primary', 'my-class-name'], //指定包裹元素的CSS類
classNameBindings: ['urgent', 'secondClassName:scn', 'isEnabled:enabled:disabled', 'stringValue'],
urgent: true,
secondClassName: true,
isEnabled: true, //如果這個屬性為true,類enabled將被渲染到nav標(biāo)簽上,如果屬性值為false類disabled將被渲染到nav標(biāo)簽上,類似于三目運算
stringValue: 'renderedClassName'
});
此時頁面的HTML源碼就有點不一樣了。renderedClassName
作為CSS類名被渲染到了nav
標(biāo)簽上。
……
對于這點需要特別注意。Ember對于Boolean
值和其他值的判斷結(jié)果是不一樣的。
在前面兩點介紹了包裹組件的HTML元素的標(biāo)簽名、CSS類名,在HTML標(biāo)簽上出來CSS類另外一個最常用的就是屬性,那么Ember同樣提供了自定義包裹HTML元素的屬性的方法。使用attributeBindings
屬性指定,這個屬性的屬性方式與classNameBindings
基本一致。
為了與前面的例子區(qū)別開新建一個組件link-items
,使用命令ember g component link-items
創(chuàng)建。
這是個組件
在模板中調(diào)用組件。
{{customizing-component-element}}
<br><br>
{{link-items}}
下面設(shè)置組件類,指定包裹的HTML標(biāo)簽為a
標(biāo)簽,并增加一個屬性href
。
// app/components/link-items.js
import Ember from 'ember';
export default Ember.Component.extend({
tagName: 'a',
attributeBindings: ['href'],
href: 'http://www.google.com.hk'
});
頁面重新加載之后得到如下結(jié)果:
比較簡單,對于渲染之后的結(jié)果我就不過多解釋了,請參考classNameBindings
屬性理解。
到此,有關(guān)于組件渲染之后包裹組件的HTML標(biāo)簽的相關(guān)設(shè)置介紹完畢。內(nèi)容不多,classNameBindings
和attributeBindings
這兩個屬性的使用方式基本相同。如有疑問歡迎給我留言或者直接查看官方教程。
博文完整代碼放在Github(博文經(jīng)過多次修改,博文上的代碼與github代碼可能有出入,不過影響不大!),如果你覺得博文對你有點用,請在github項目上給我點個star
吧。您的肯定對我來說是最大的動力??!
更多建議: