Ember 自定義包裹組件的HTML標簽

2018-01-06 17:53 更新

按照慣例,先做好準備工作,使用Ember CLI命令生成演示所需的文件:

  1. ember g route customizing-component-element
  2. ember g component customizing-component-element
  3. ember g route home
  4. ember g route about

默認情況下,組件會被包裹在div標簽內(nèi)。比如,組件渲染之后得到下面的代碼:

  1. <div id="ember180" class="ember-view">
  2. <h2>My Component</h2>
  3. </div>

h1標簽就是組件的內(nèi)容。以ember開頭的idclass都是Ember自動生成的。如果你需要修改渲染之后生成的HTML不是被包裹在div標簽,或者修改idclass等屬性值為自定義的值,你可以在組件類中設置。

1,自定義包裹組件的HTML標簽

默認情況下,組件會被包裹在div標簽內(nèi),如果你需要修改這個默認值你可以在組件類中指定這個包裹的HTML標簽。

  1. // app/components/customizing-component-element.js
  2. import Ember from 'ember';
  3. export default Ember.Component.extend({
  4. // 使用tabName屬性指定渲染之后HTML標簽
  5. // 注意屬性的值必須是標準的HTML標簽名
  6. tagName: 'nav'
  7. });

下面自定義一個組件。

  1. <ul>
  2. <li>{{#link-to 'home'}}Home{{/link-to}}</li>
  3. <li>{{#link-to 'about'}}About{{/link-to}}</li>
  4. </ul>

下面是調(diào)用組件的模板代碼。注意組件被包裹在那個HTML標簽內(nèi),正確情況下應該是被包裹在nav標簽中。

  1. {{customizing-component-element}}

頁面加載之后查看頁面的源代碼。如下:

結(jié)果HTML代碼

可以看到組件customizing-component-element的內(nèi)容確實是被包裹在nav標簽之中,如果在組件類中沒有使用屬性tagName指定包裹的HTML標簽,默認是div,你可以把組件類中tagName屬性刪除之后再查看頁面的HTML源碼代碼。

2,自定義包裹組件的HTML元素的類名

默認情況下,Ember會自動為包裹組件的HTML元素增加一個以ember開頭的類名,如果你需要增加自定義的CSS類,可以在組件類中使用className數(shù)組屬性指定,可以一次性指定多個CSS類。比如下面的代碼例子:

  1. // app/components/customizing-component-element.js
  2. import Ember from 'ember';
  3. export default Ember.Component.extend({
  4. // 使用tabName屬性指定渲染之后HTML標簽
  5. // 注意屬性的值必須是標準的HTML標簽名
  6. tagName: 'nav',
  7. classNames: ['primary', 'my-class-name'] //指定包裹元素的CSS類
  8. });

頁面重新加載之后查看源代碼,可以看到nav標簽中多了兩個CSS類,一個是primary,一個是my-class-name。

  1. ……

如果你想根據(jù)某個數(shù)據(jù)的值決定是否增加CSS類也是可以做到的,比如下面的代碼,當urgenttrue的時增加一個CSS類urgent,否則不增加這個類。要達到這個目的可以通過屬性classNameBindings設置。

  1. // app/components/customizing-component-element.js
  2. import Ember from 'ember';
  3. export default Ember.Component.extend({
  4. // 使用tabName屬性指定渲染之后HTML標簽
  5. // 注意屬性的值必須是標準的HTML標簽名
  6. tagName: 'nav',
  7. classNames: ['primary', 'my-class-name'], //指定包裹元素的CSS類
  8. classNameBindings: ['urgent'],
  9. urgent: true
  10. });

頁面重新加載之后查看源代碼,可以看到nav標簽中多了一個CSS類urgent,如果屬性urgent的值為false,CSS類urgent將不會渲染到nav標簽上。

  1. ……

注意classNameBindings指定的屬性值必須要跟用于判斷數(shù)據(jù)的屬性名一致,比如這個例子中classNameBindings指定的屬性值是urgent,用戶判斷是否增加類的屬性也是urgent。如果這個屬性只是駝峰式命名的那么渲染之后CSS類名將是以中劃線-分隔,比如classNameBindings指定一個名為secondClassName,渲染后的CSS類為second-class-name。比如下面的演示代碼:

  1. // app/components/customizing-component-element.js
  2. import Ember from 'ember';
  3. export default Ember.Component.extend({
  4. // 使用tabName屬性指定渲染之后HTML標簽
  5. // 注意屬性的值必須是標準的HTML標簽名
  6. tagName: 'nav',
  7. classNames: ['primary', 'my-class-name'], //指定包裹元素的CSS類
  8. classNameBindings: ['urgent', 'secondClassName'],
  9. urgent: true,
  10. secondClassName: true
  11. });

頁面重新加載之后查看源代碼,可以看到nav標簽中多了一個CSS類second-class-name。

  1. ……

如果你不想渲染之后的CSS類名被修改為中劃線分隔形式,你可以值classNameBindings屬性中指定渲染之后的CSS類名。比如下面的代碼:

  1. // app/components/customizing-component-element.js
  2. import Ember from 'ember';
  3. export default Ember.Component.extend({
  4. // 使用tabName屬性指定渲染之后HTML標簽
  5. // 注意屬性的值必須是標準的HTML標簽名
  6. tagName: 'nav',
  7. classNames: ['primary', 'my-class-name'], //指定包裹元素的CSS類
  8. classNameBindings: ['urgent', 'secondClassName:scn'], //指定secondClassName渲染之后的CSS類名為scn
  9. urgent: true,
  10. secondClassName: true
  11. });

頁面重新加載之后查看源代碼,可以看到nav標簽中原來CSS類為second-class-name的變成了scn

  1. ……

有沒有感覺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的設計理念是“約定優(yōu)于配置”!所以很多的屬性默認的設置都是我們平常開發(fā)中最常用的格式。

除了上述可以指定CSS類名之外,還可以在classNameBindings增加簡單的邏輯,特別是在處理一些動態(tài)效果的時候上述特性是非常有用的。

  1. // app/components/customizing-component-element.js
  2. import Ember from 'ember';
  3. export default Ember.Component.extend({
  4. // 使用tabName屬性指定渲染之后HTML標簽
  5. // 注意屬性的值必須是標準的HTML標簽名
  6. tagName: 'nav',
  7. classNames: ['primary', 'my-class-name'], //指定包裹元素的CSS類
  8. classNameBindings: ['urgent', 'secondClassName:scn', 'isEnabled:enabled:disabled'],
  9. urgent: true,
  10. secondClassName: true,
  11. isEnabled: true //如果這個屬性為true,類enabled將被渲染到nav標簽上,如果屬性值為false類disabled將被渲染到nav標簽上,類似于三目運算
  12. });

正如代碼的注釋所說的,isEnabled:enabled:disabled可以理解為一個三目運算,會根據(jù)isEnabled的值渲染不同的CSS類到nav上。

下面的HTML代碼是isEnabledtrue的情況,對于isEnabledfalse的情況請讀者自己試試:

  1. ……

注意:如果用于判斷的屬性值不是一個Boolean值而是一個字符串那么得到的結(jié)果與上面的結(jié)果是不一樣的,Ember會直接把這個字符串的值作為CSS類名渲染到包裹的標簽上。比如下面的代碼:

  1. // app/components/customizing-component-element.js
  2. import Ember from 'ember';
  3. export default Ember.Component.extend({
  4. // 使用tabName屬性指定渲染之后HTML標簽
  5. // 注意屬性的值必須是標準的HTML標簽名
  6. tagName: 'nav',
  7. classNames: ['primary', 'my-class-name'], //指定包裹元素的CSS類
  8. classNameBindings: ['urgent', 'secondClassName:scn', 'isEnabled:enabled:disabled', 'stringValue'],
  9. urgent: true,
  10. secondClassName: true,
  11. isEnabled: true, //如果這個屬性為true,類enabled將被渲染到nav標簽上,如果屬性值為false類disabled將被渲染到nav標簽上,類似于三目運算
  12. stringValue: 'renderedClassName'
  13. });

此時頁面的HTML源碼就有點不一樣了。renderedClassName作為CSS類名被渲染到了nav標簽上。

  1. ……

對于這點需要特別注意。Ember對于Boolean值和其他值的判斷結(jié)果是不一樣的。

3,自定義包裹組件的HTML元素的屬性

在前面兩點介紹了包裹組件的HTML元素的標簽名、CSS類名,在HTML標簽上出來CSS類另外一個最常用的就是屬性,那么Ember同樣提供了自定義包裹HTML元素的屬性的方法。使用attributeBindings屬性指定,這個屬性的屬性方式與classNameBindings基本一致。 為了與前面的例子區(qū)別開新建一個組件link-items,使用命令ember g component link-items創(chuàng)建。

  1. 這是個組件

在模板中調(diào)用組件。

  1. {{customizing-component-element}}
  2. <br><br>
  3. {{link-items}}

下面設置組件類,指定包裹的HTML標簽為a標簽,并增加一個屬性href

  1. // app/components/link-items.js
  2. import Ember from 'ember';
  3. export default Ember.Component.extend({
  4. tagName: 'a',
  5. attributeBindings: ['href'],
  6. href: 'http://www.google.com.hk'
  7. });

頁面重新加載之后得到如下結(jié)果:

渲染后的HTML代碼

比較簡單,對于渲染之后的結(jié)果我就不過多解釋了,請參考classNameBindings屬性理解。

到此,有關于組件渲染之后包裹組件的HTML標簽的相關設置介紹完畢。內(nèi)容不多,classNameBindingsattributeBindings這兩個屬性的使用方式基本相同。如有疑問歡迎給我留言或者直接查看官方教程。

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

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

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號