2015年4月22日 星期三

Hybrid Apps開發系列之4.3:多頁面App程式 (清單/細節瀏覽)

「列出清單,點選之後顯示該清單項目的細節」-這是apps最常出現的操作模式之一,例如:
圖1. 左邊是清單,點選項目後會出現該項目細節
要完成這樣的功能除了需要完成兩個頁面:「清單頁面」與「細節瀏覽頁面」之外,還必須讓「清單頁面」傳遞參數-例如「清單項目編號」給「細節瀏覽頁面」,如此後者才能正確取得細節資料。



為了讓頁面傳遞參數,Ionic/AngularJS提供了$stateParams服務,透過此服務,搭配.config() states內的url設定,就能將參數傳遞到下一個頁面,如下圖:
圖2. 透過$stateParams服務,同時正確設定state的url格式,便可傳遞參數。
如圖2所示,「細節瀏覽」頁面的state,必須加入":參數名稱",如圖'/home/:sid",sid便是參數名稱。之後$stateParams.sid便可存取其值。另外,要留意的是:「細節瀏覽」頁面的url必須是來源頁面(即「清單頁面」)的url加上"/:參數名稱"所構成。

因此,圖1所構成的瀏覽模式,其app.js如下:
angular.module('starter', ['ionic','starter.controllers'])
        .config(function($stateProvider, $urlRouterProvider){
            $urlRouterProvider.otherwise('/home');
            $stateProvider
                    .state('home',{
                        url: '/home',
                        templateUrl: 'templates/home.html',
                        controller: 'homeCtrl'
                    })
                    .state('details',{
                        url: '/home/:sid',
                        templateUrl: 'templates/details.html',
                        controller: 'detailsCtrl'
                    })            
        })

states說明

  • 第1行:starter模組的相依參數部份,除了ionic模組外,多了自訂模組'starter.controllers',這是因為將所有controllers都放到另一個.js檔的緣故。
  • 第11行:'details'這個state的url必須加入傳遞參數的名稱,例如sid,格式則是':參數名稱',如範例所示 ':sid'
controllers.js檔案內容如下:
angular.module('starter.controllers',[])
        .controller('homeCtrl',function($scope){
            $scope.stocks = stocklist;
        })
        .controller('detailsCtrl',function($scope,$stateParams){
            $scope.stock = stocklist[$stateParams.sid];
        })
var stocklist = [
    {id: 2330, name: '台積電', price: 147.0, PER: 14.44, PBR: 3.65,
        yield: 3.06, Desc: '晶圓製造'},
    {id: 1301, name: '台塑', price: 76.5, PER: 27.03, PBR: 1.7,
        yield: 2.22, Desc: '聚氯乙烯(PVC)、氯乙烯等塑膠製品'},
    {id: 2002, name: '中鋼', price: 25.8, PER: 18.04, PBR: 1.33,
        yield: 3.88, Desc: '鋼品設計製造買賣儲運及其他相關業務'},
    {id: 3045, name: '台灣大', price: 108.0, PER: 19.42, PBR: 6.13,
        yield: 5.19, Desc: '通訊業'},
    {id: 2454, name: '聯發科', price: 421.5, PER: 14.03, PBR: 2.68,
        yield: 3.56, Desc: '多媒體IC 、電腦週邊IC、其他IC'},
    {id: 2317, name: '鴻海', price: 93.1, PER: 10.52, PBR: 1.48,
        yield: 1.93, Desc: '電腦系統設備連接器等之開發設計製造'},
    {id: 3008, name: '大立光', price: 2695.0, PER: 18.6, PBR: 7.83,
        yield: 1.06, Desc: '各式光學鏡頭模組研發設計生產銷售'}
]

controllers說明

  • 第1行:定義controller模組,名稱為"starter.controllers",必須與app.js指定的名稱相符。
  • 第2-4行:定義homeCtrl,以$scope定義資料模型變數stocks,供頁面home.html使用,其值為8-23行的資料陣列。
  • 第5-7行:定義detailsCtrl,供details.html使用。由於要接收home頁面傳送過來的參數,因此,必須使用$stateParams服務。而$stateParams.sid便是傳送過來的參數。此外,也定義了stock資料模型變數,其值為根據傳送過來的參數值,所對應的陣列元素。
  • 第8-23行:資料陣列。Ionic/AngularJS有其他服務可從網路中取得資料。後續範例會將資料部份改為從網路擷取。

頁面說明

清單列表頁面home.html如下:
<ion-view title="清單">
    <ion-nav-bar>
    </ion-nav-bar>
    <ion-content>
        <div class="list">
            <div class="item" ng-repeat="item in stocks">
                <a href="#/home/{{$index}}">{{item.id}} {{item.name}}</a>
            </div>
        </div>
    </ion-content>
</ion-view>
  • 第6行:ng-repeat指令重複產生6-8行的div,內容部份則是靠controller端$scope定義的資料模型陣列變數stocks,將資料綁定至頁面來。
  • 第7行:每一清單項目以超連結的方式設定url。其中'#/home/'是基本網址,$index則是陣列stocks的索引值,由0開始編號。
細節瀏覽頁面details.html如下:
<ion-view title="{{stock.name}}">
    <ion-nav-bar>
        <ion-nav-back-button></ion-nav-back-button>
    </ion-nav-bar>
    <ion-content>
        <div class="list card">
            <div class="item item-icon-left">
                <i class="icon ion-podium"></i>
                <h2>{{stock.id}}{{stock.name}}</h2>
                <p>{{stock.Desc}}</p>
            </div>
            <div class="item item-body">
                <div class="row">
                    <div class="col">股價<br>{{stock.price}}</div>
                    <div class="col">本益比<br>{{stock.PER}}</div>
                </div>
                <div class="row">
                    <div class="col">股價淨值比<br>{{stock.PBR}}</div>
                    <div class="col">殖利率<br>{{stock.yield}}%</div>
                </div>                
            </div>
        </div>
    </ion-content>
</ion-view>


最後,記得在index.html加入controllers.js檔:
[...略...]  
<!-- your app's js -->
    <script src="js/app.js"></script>
    <script src="js/controllers.js"></script>
  </head>
  <body ng-app="starter">
  <ion-nav-view></ion-nav-view>
  </body>
</html>

JS Bin線上展示如下:JS Bin

沒有留言:

張貼留言