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