ionic入門教程第十八課-初識自定義指令directive oni-bar(tab-bar)

通過這麼長時間的學習,我想你們都有了必定的基礎了。css

這節課嘗試着給你們講點更加深刻的東西,能理解的就好好學學,還理解不來的朋友也沒關係,能夠當作擴展閱讀看看就好。html

學習切忌過於急躁。ios

到目前爲止,我教程裏面提到的內容都是使用了ionic的內置指令和一些angularjs的內置指令來實現的。如ion-nva-bar、ion-list、ion-nav-view和ng-repeat、ng-bind等angularjs

其中ion是ionic的命名空間,ng是angularjs的命名空間,- 後面的是指令的名字。web

若是你使用的ide是webstorm,而且安裝了angularjs的插件,那你能夠在文件中鍵入「ngdc」快速建立指令api

不使用快捷方式的,能夠新建一個文件。(我本身也沒用過快捷建立,感受格式跟我寫的不是很同樣。)微信

鍵入angular.module().directive(name,function factory(){})app

這裏我先不對全部的API進行講解,咱們先拿一個簡單的實例來講明。webstorm


咱們要完成一個這樣的在bar中的tab頁。ionic

首先咱們新建一個項目ionic start onibartest tabs

而後使用webstorm打開項目,關於目錄結和初始化運行結果的內容這裏就不說了,前面的教程裏都提到過了。

而後咱們分析一下,咱們要的效果是在一個bar裏面有一個切換頁,而後左邊有一個按鈕,右邊有一個按鈕。

因爲要重寫這個bar,因此首先咱們註釋掉新建項目中的bar代碼


而後本身放上一個

<ion-header-bar class="bar bar-header" align-title="center">
</ion-header-bar>
運行起來會在界面上看到一個空白的bar。

而後咱們處理左邊的按鈕。這裏隨口說一些這個按鈕,有兩種方式實現。

一、放上一個div定義class是buttons,聲明這是一個按鈕組,在標籤內的第一個buttons,會被當作是左邊的按鈕,第二個就是右邊的按鈕了。

<div class="buttons">
  <button class="button button-icon icon ion-navicon-round" >
  </button>
</div>

二、放上ion-bav-buttons 定義side  left左邊  right右邊 

<ion-nav-buttons side="left">
    <button class="button button-icon icon ion-navicon-round" >
    </button>
</ion-nav-buttons>
這裏咱們隨意點用了第一種方法實現。一樣處理了右邊的按鈕。

接着咱們處理中間的tab。根據bar的佈局,咱們能夠把中間的tab頁,當作就是當前頁面的標題。

因此,隨意這麼處理。這不是本節課的重點。

<div class="title">
  <ion-tabs class="tabs-striped" >
    <div ng-repeat="item in onibaritems">
      <ion-tab title="{{item.title}}" href="{{item.href}}"></ion-tab>
    </div>
  </ion-tabs>
</div>
定義ng-repeat是爲了是中間的tab項支持配置。這裏又有一個小細節,順便提一下。這裏ng-repeat的element使用了一個div做爲對象。

可是咱們經常使用的ion-tabs 和ion-tab的組合並無這個div。用這個div的目的是若是在ion-tabs中使用ng-repeat那麼出來的循環就是tabs的循環。

若是在tab中使用ng-repeat那就找不到item對象。這是由於ion-tabs和ion-tab都是ionic自帶的指令,都會通過編譯變成一些複雜元素的集合體。

很差控制循環對象,因此這裏在加入一層div處理這個bug。說了一堆,說不清楚,看不懂的就當我沒說。可有可無的。

而後由於這個bar放的位置是在index文件,這裏我簡單的使用rootscope,來定義了onibaritems

最後的代碼就是

html


js


運行結果


爲了使這個tab好看點,在style文件中加入樣式。


運行結果如效果圖所示。這裏就不重複上圖了。


接下來咱們開始講解如何把咱們上面說到的全部東西編寫成指令呢。

爲何我要在前面講這麼一大堆,就是想讓你們明白一個過程,指令作的事情就是把你定義好的這些屬性和樣式編譯出來。

能夠理解爲最後編譯出來的html和上面所寫的是同樣的。

首先咱們在www/js文件夾下新建一個文件夾directives而後新建一個文件OniBarDirective.js


首先這裏須要關注的是oniBar,這個指令的名字,使用的是駝峯式的寫法。那麼在模板中就可使用oni-bar。

1、根據咱們前面的定義,這個指令是要被編譯成元素的。因此咱們加入第一個參數restrict:'E'

restrict接受4個參數或者這4個參數的任意組合,E:元素、A:屬性、C:樣式表、M:註釋。不理解的先無論,後續的課程會再將這個

2、而後把咱們開始寫的html代碼拷貝進來,修改爲一行字符串。若是屬性是用雙引號的,先後加上單引號把縮進去掉就能夠了。加入第二個參數,注意如下內容是單行的

template:'<ion-header-bar class="bar bar-header" align-title="center"><div class="buttons"><button class="button button-icon icon ion-navicon-round" ></button></div><div class="title"><ion-tabs class="tabs-striped" ><div ng-repeat="item in items"><ion-tab title="{{item.title}}" href="{{item.href}}"></ion-tab></div></ion-tabs></div><div class="buttons"><button class="button button-icon icon ion-ios-search" > </button> </div> </ion-header-bar>',
上面這個字符串和最上面提到的html頁面的內容是同樣的,我爲了作區分把ng-repeat裏面onibaritems改爲items。下面會提到這兩個數據傳輸。

3、接下來加入第三個參數replace:true,

replace接受兩個參數true表示會替換指令所在的元素。false指令的html會被編譯到躲在元素的內部(追加)

這裏能夠換種概念理解,設置爲true則表示它本身就是父級。父級的內容會被覆蓋掉。false表示它是父級的子級,保留父級的其餘兄弟子級。

4、接下來咱們使用link函數:link:function postLink(scope,element,attrs){}

這裏自動傳入三個參數scope:做用域 element綁定數據的對象 attrs對象的全部屬性。

這裏咱們利用attrs對象的屬性來進行傳值。這裏須要注意的是外面的對象傳進來會變成一個字符串,因此要作轉換

link: function(scope, element, attrs) {
  scope.items = JSON.parse(attrs.items);
}
在html中使用 < oni-bar items= "{{ onibatitems }}" ></ oni-bar >

完成的指令代碼以下:

注意使用時要引用文件,而後在app.js文件中加入

angular.module('starter', ['ionic', 'starter.controllers', 'starter.services','starter.directives'])
5、細心的朋友應該已經發現了,咱們還有一部分的內容---樣式表是獨立在這個指令以外的,也就是說要另外引用相關的樣式文件才能使得這個指令達到預期的效果。

因此咱們把style文件中的css樣式剪切出來也加到指令裏面。

最終整個指令的代碼以下:

angular.module('starter.directives', [])
  .directive('oniBar', [function() {
    return {
        restrict: 'E',
        template:'<ion-header-bar class="bar bar-header" align-title="center"><div class="buttons"><button class="button button-icon icon ion-navicon-round" ></button></div><div class="title"><ion-tabs class="tabs-striped" ><div ng-repeat="item in items"><ion-tab title="{{item.title}}" href="{{item.href}}"></ion-tab></div></ion-tabs></div><div class="buttons"><button class="button button-icon icon ion-ios-search" > </button> </div> </ion-header-bar>',
        replace:true,
        controller: function(){
            var style = window.document.createElement('style');
            style.type = 'text/css';
            style.innerHTML += '.tabs .tab-title{font-family:"微軟雅黑" !important;}';
            style.innerHTML += '.tabs-striped .tab-item.tab-item-active, .tabs-striped .tab-item.active, .tabs-striped .tab-item.activated {margin-top: 0px;border-style: solid;border-width: 0 0 3px 0;border-color: #FF7A01; }';
            style.innerHTML += '.tabs-striped .tabs{border-bottom: 0px solid #ddd !important;}';
            style.innerHTML += '.tab-item{font-size: 17px;}';
            style.innerHTML += '.bar .title{margin: 1px 37px;}';
            window.document.getElementsByTagName('head')[0].appendChild(style);
        },
        link: function(scope, element, attrs) {
            scope.items = JSON.parse(attrs.items);
        }
    }
}])
這樣子這個指令纔是一個完整的總體。

這節課的目的只是讓你們對這個自定義指令有一個基本的感知。我後續會出一節或者兩節來詳細講解相關的api。

你們都知道ionic的tab在安卓和ios環境下是不一樣的,因此若是在安卓環境下運行這個指令,那將看不到中間切換頁的文字

因此咱們能夠在config中加入

使得tab在兩個平臺上的表現一致。


Demo地址:http://pan.baidu.com/s/1o85uIng


你們還有其餘的問題能夠經過如下方式找到我
新浪微博:小虎Oni
微信公衆號:ionic__
公衆號最近沒時間維護,但仍是但願你們關注,謝謝


相關文章
相關標籤/搜索