一.ionic中路由管理介绍:
在单页应用中,路由的管理是很重要的环节。ionic.js没有使用AngularJS内置的ng-route路由,而是选择了AngularUI项目的ui-router模块。
ui-router的核心理念是将子视图集合抽象为一个状态机,导航意味着状态的切换。在不同的状态下,ionic.js渲染对应的子视图(动态加载的HTML片段)就实现了路由导航的功能。
二.ionic中内联模板介绍
HTML中常用的script标签在AngularJS中被重新定义了:除了原本的脚本声明功能之外,如果script元素的type属性定义为text/ng-template,则被称为内联模板。
内联模板在单页应用(SAP)开发中非常有用。SAP应用通常需要通过AJAX从后台载入众多的HTML片段。这些HTML片段都用文件存放的话,看起来会非常杂乱。使用内联模块,就可以把这些零散的HTML片段模板都集中在一个文件里,维护和开发的感觉都会好很多。
AngularJS在编译时会将内联模板的id属性值和其内容,分别作为key和value,存入$templateCache管理的hash表中。
内联模板的使用,常见的有几种情况:
- 使用ng-include指令
<div ng-include="'a.html'"></div>
注意:其中a..html是一个字符串常量,需要使用单引号包裹起来。
- 使用$templateCache服务
var partial=$templateCache.get("a.html")
- 使用$http服务
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no,width=device-width,height=device-height">
<script src="../../lib/js/ionic.bundle.min.js"></script>
<link rel="stylesheet" type="text/css" href="../../lib/css/ionic.min.css">
</head>
<body ng-controller="firstCtrl">
<ion-header-bar class="bar-positive">
<h1 class="title">内联模板</h1>
<a class="button" ng-click="load()">载入</a>
</ion-header-bar>
<ion-content padding="true" >
<div id="container"></div>
</ion-content>
<!--模板定义-->
<script id="home.html" type="text/ng-template">
<p>鲁智深因见山水秀丽,贪行了半日,赶不上宿头,路中又没人作伴,那里投宿是好。又赶了三二十里田地,过了一条板桥,远远地望见一簇红霞,树木丛中,闪着一所庄院。庄后重重叠叠,都是乱山。鲁智深道:“只得投庄上去借宿。”迳奔到庄前看时,见数十个庄家,忙忙急急,搬东搬西。鲁智深到庄前,倚了禅杖,与庄客打个问讯。庄客道:“和尚,日晚来我庄上做甚的?”智深道:“小僧赶不上宿头,欲借贵庄投宿一宵,明早便行。”庄客道:“我庄上今夜有事,歇不得。”智深道:“胡乱借洒家歇一夜,明日便行。”庄客道:“和尚快走,休在这里讨死。”智深道:“也是怪哉!歇一夜打甚么不紧,怎地便是讨死?”庄家道:“去便去,不去时,便捉来缚在这里。”鲁智深大怒道:“你这厮村人,好没道理!俺又不曾说甚的,便要绑缚洒家。”庄家们也有骂的,也有劝的。鲁智深提起禅杖,却待要发作,只见庄里走出一个老人来。但见:主髭须似雪,发鬓如霜。行时腰曲头低,坐后耳聋眼暗。头裹三山暖帽,足穿四缝宽靴。腰间绦系佛头青,身上罗衫鱼肚白。好似山前都土地,正如海底老龙君。</p>
</script>
</body>
</html>
<script>
angular.module("myApp", ["ionic"])
.controller("firstCtrl",function($scope,$http,$templateCache){
$scope.load = function(){
$http.get("home.html",{cache:$templateCache})
.success(function(data,status){
var el = document.querySelector("#container");
angular.element(el).html(data);
})
.error(function(data,status){})
};
$scope.load();
});
</script>
三.ionic路由机制:状态 对于视图的路由,ionic没有使用AngularJS的路由模块(ng-route),而是使用了angular-ui项目的ui-route模块。ionic.bundle.js已经打包好了ui-route模块,所以我们使用时不需要单独引入。 和通常基于url匹配的路由机制不同,ui-route是基于状态机的导航:
可以认为视图元素ui-view有多个状态,比如:state1/state2/state3。在任何一个时刻,视图元素只能处于某一个状态下。这些状态是由状态机管理的。 在ui-route中的$state服务就是一个状态机实例,在任何时刻,我们可以使用其 go()方法跳转到指定名称的状态。
配置状态机
需要指出的是,状态的划分以及每个状态的元信息(比如模板、url等)是在配置 阶段通过$stateProvider完成的:
angular.module("myApp",["ionic"])
.config(function($stateProvider){
$stateProvider.state("state1",{...})
.state("state2",{...})
.state3("state3",{...});
});
触发状态迁移的几种方式(通俗的讲就是页面跳转的几种方式)
1. 调用$state.go()方法,这是一个高级的便利方法;
2. 点击包含ui-sref指令的链接 <a ui-sref="state1">Go State 1</a>
3. 导航到与状态相关联的 url。
当用户点击这个链接时,$state服务将根据状态名state1 找到对应的元信息,提取、编译模板,并将其显示在ui-view指令指定的 视图窗口中。
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no,width=device-width,height=device-height">
<script src="../../lib/js/ionic.bundle.min.js"></script>
<link rel="stylesheet" type="text/css" href="../../lib/css/ionic.min.css">
</head>
<body ng-controller="firstCtrl">
<!--视图容器-->
<div ui-view></div>
<!--内联模板: home.html-->
<script id="home.html" type="text/ng-template">
<div class="bar bar-header bar-positive">
<h1 class="title">主页</h1>
</div>
<div class="scroll-content has-header">
<ul class="list list-inset">
<li class="item item-icon-right" ui-sref="music">
音乐!
<i class="icon ion-ios-arrow-right"></i>
</li>
<li class="item item-icon-right" ui-sref="sport">
运动!
<i class="icon ion-ios-arrow-right"></i>
</li>
</ul>
</div>
</script>
<!--内联模板: music.html-->
<script id="music.html" type="text/ng-template">
<div class="bar bar-header bar-energized">
<h1 class="title">音乐</h1>
</div>
<div class="scroll-content has-header">
<ul class="list list-inset">
<li class="item item-icon-right" ui-sref="home">
主页!
<i class="icon ion-ios-arrow-right"></i>
</li>
<li class="item item-icon-right" ui-sref="sport">
运动!
<i class="icon ion-ios-arrow-right"></i>
</li>
</ul>
</div>
</script>
</body>
</html>
<script>
angular.module("myApp", ["ionic"])
.config(function($stateProvider,$urlRouterProvider) {
//配置状态机
$stateProvider
.state("home", {
templateUrl: "home.html" //内联模板的id
})
.state("music", {
templateUrl: "music.html" //内联模板的id
});
})
.controller("firstCtrl",function($scope,$state){
//切换到状态 : home
$state.go("home");
});
</script>
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no,width=device-width,height=device-height">
<script src="../../lib/js/ionic.bundle.min.js"></script>
<link rel="stylesheet" type="text/css" href="../../lib/css/ionic.min.css">
</head>
<body ng-controller="firstCtrl">
<script id="map.html" type="text/ng-template">
<ion-header-bar class="bar-positive">
<h1 class="title">地图</h1>
<a ui-sref="novel" class="button">小说</a>
</ion-header-bar>
<ion-content padding="true">
<img src="img/firefox-logo.png">
</ion-content>
</script>
<script id="novel.html" type="text/ng-template">
<ion-header-bar class="bar-balanced">
<h1 class="title">小说</h1>
<a ui-sref="map" class="button">地图</a>
</ion-header-bar>
<ion-content padding="true">
<p ng-include="'xiaoshuo.txt'"></p>
</ion-content>
</script>
<ion-nav-view></ion-nav-view>
</body>
</html>
<script>
var app = angular.module("myApp", ["ionic"]);
app.config(function($stateProvider,$urlRouterProvider) {
$stateProvider
.state("map", {
templateUrl: "map.html"
})
.state("novel", {
url: "novel",
templateUrl: "novel.html"
});
})
.controller("firstCtrl",function($scope,$state){
$state.go("map");
});
</script>
5.模板视图:ion-view: 尽管在模板视图中可以随便写HTML,但是,在ionic中,我们总是使用指令ion-view来 作为模板视图内容的容器,这是为了与ionic的导航框架保持兼容:
<script id="..." type="text/ng-template">
<ion-view> <!--模板视图内容--> </ion-view>
</script>
ion-view指令有一些可选的属性:
- view-title - 视图标题文字
- cache-view - 是否对这个模板视图进行缓存
- hide-back-button -是否隐藏导航栏中的返回按钮
- hide-nav-bar - 是否隐藏导航栏
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no,width=device-width,height=device-height">
<script src="../../lib/js/ionic.bundle.min.js"></script>
<link rel="stylesheet" type="text/css" href="../../lib/css/ionic.min.css">
</head>
<body ng-controller="firstCtrl">
<!--导航框架之导航栏-->
<ion-nav-bar class="bar-positive" align-title="left"></ion-nav-bar>
<!--导航框架之导航视图-->
<ion-nav-view></ion-nav-view>
<!--内联模板:home.html-->
<script id="home.html" type="text/ng-template">
<!-- 导航框架之模板视图 -->
<ion-view view-title="Home">
<ion-content>
<ion-list type="list-inset">
<ion-item ui-sref="music" class="item-icon-right">
Go to music page!
<i class="icon ion-ios-arrow-right"></i>
</ion-item>
</ion-list>
</ion-content>
</ion-view>
</script>
<!--内联模板:music.html-->
<script id="music.html" type="text/ng-template">
<!--ion-view 的title 属性值将显示在导航栏中-->
<ion-view view-title="Music">
<ion-content class="padding">
<a class="button ion ion-home" ui-sref="home">go home</a>
</ion-content>
</ion-view>
</script>
</body>
</html>
<script>
var app = angular.module("myApp", ["ionic"]);
app.config(function($stateProvider,$urlRouterProvider) {
$stateProvider
.state("home", {
templateUrl: "home.html"
})
.state("music", {
templateUrl: "music.html"
});
})
.controller("firstCtrl",function($scope,$state){
$state.go("home");
});
</script>
7. 回退按钮 : ion-nav-back-button
ionic的指令ion-nav-back-button指令可以自动地让你回退到前一个视图:
当视图切换时,回退按钮会自动出现在导航条中,并显示前一个视图 的标题。点击回退按钮将返回前一个视图。<ion-nav-bar> <ion-nav-back-button></ion-nav-back-button> </ion-nav-bar>
ion-nav-back-button定制样式,我们可以定制回退按钮的图标、文本和样式:
8. 视图特定按钮 : ion-nav-buttons<ion-nav-back-button class="button-clear"> <i class="icon ion-ios-arrow-back"></i> 返回 </ion-nav-back-button>
在ionic的导航框架中,导航栏是公共资源。那么,如果我们需要在不同的 状态下(即载入不同的模板视图),在导航栏上显示一些不同的按钮,该怎么办? 答案是,在ion-view指令声明的元素内使用ion-nav-buttons指令 添加一组按钮,ionic的导航框架看到这个指令时,就会自动地将这些按钮 安置到导航栏中。 指令ion-nav-buttons必须是指令ion-view的直接后代:
<ion-view> <ion-nav-buttons> <!--按钮定义--> </ion-nav-buttons> </ion-view>
ion-nav-buttons指令有一个属性用于声明这些按钮在导航栏中的位置:
- side - 在导航条的那一侧放置按钮。允许值:primary | secondary | left | right
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no,width=device-width,height=device-height">
<script src="../../lib/js/ionic.bundle.min.js"></script>
<link rel="stylesheet" type="text/css" href="../../lib/css/ionic.min.css">
</head>
<body ng-controller="myCtrl">
<!--导航框架之导航栏-->
<ion-nav-bar class="bar-positive">
<ion-nav-back-button></ion-nav-back-button>
</ion-nav-bar>
<!--导航框架之导航视图-->
<ion-nav-view></ion-nav-view>
<script id="home.html" type="text/ng-template">
<!--导航框架之模板视图-->
<ion-view view-title="Home">
<!--本视图可见时,ion-nav-buttons将被导航框架载入导航栏-->
<ion-nav-buttons side="right">
<button class="button" ng-click="doSomething()">
register
</button>
</ion-nav-buttons>
<ion-nav-buttons side="left">
<button class="button" ng-click="doSomething()">
Login
</button>
</ion-nav-buttons>
<ion-content>
<ion-list>
<ion-item ui-sref="music" class="item-icon-right">
Go to music page!
<i class="icon ion-chevron-right"></i>
</ion-item>
</ion-list>
</ion-content>
</ion-view>
</script>
<script id="music.html" type="text/ng-template">
<!--导航框架之模板视图-->
<ion-view view-title="Music">
<!--本视图可见时,ion-nav-buttons将被导航框架载入导航栏-->
<ion-nav-buttons side="right">
<button class="button" ng-click="doSomething()">
Play
</button>
</ion-nav-buttons>
<ion-content class="padding">
<!-- The content of the page -->
<a class="button ion ion-home" ui-sref="home">go home</a>
</ion-content>
</ion-view>
</script>
</body>
</html>
<script>
var app = angular.module("myApp", ["ionic"]);
app.config(function($stateProvider,$urlRouterProvider) {
$stateProvider
.state("home", {
templateUrl: "home.html"
})
.state("music", {
templateUrl: "music.html"
});
})
.controller("myCtrl",function($scope,$state){
$state.go("home");
});
</script>
9. 定制标题内容 : ion-nav-title导航栏中默认显示所载入模板视图的view-title属性值,但ionic允许我们使用 ion-nav-title指令,使用任意的HTML片段改变它!ion-nav-title必须是ion-view的直接后代:
<ion-view>
<ion-nav-title> <!--HTML片段--> </ion-nav-title>
</ion-view>
10. 定制视图切换方式 : nav-transition
视图切换时的动画转场方式,可以使用nav-transition指令声明:
<any ui-sref=".." nav-transition="..">...</any>
目前支持的转场方式有三种:- android - android模拟
- ios - ios模拟
- none - 取消转场动画
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no,width=device-width,height=device-height">
<script src="../../lib/js/ionic.bundle.min.js"></script>
<link rel="stylesheet" type="text/css" href="../../lib/css/ionic.min.css">
</head>
<body ng-controller="myCtrl">
<!--导航框架之导航栏-->
<ion-nav-bar class="bar-positive">
<ion-nav-back-button></ion-nav-back-button>
</ion-nav-bar>
<!--导航框架之导航视图-->
<ion-nav-view></ion-nav-view>
<script id="home.html" type="text/ng-template">
<!--导航框架之模板视图-->
<ion-view view-title="Home">
<ion-content>
<ion-list>
<ion-item ui-sref="music" class="item-icon-right" nav-transition="ios">
Go to music page!
<i class="icon ion-ios-arrow-right"></i>
</ion-item>
</ion-list>
</ion-content>
</ion-view>
</script>
<script id="music.html" type="text/ng-template">
<!--导航框架之模板视图-->
<ion-view view-title="Music">
<ion-content class="padding">
<a class="button ion ion-home" ui-sref="home">go home</a>
</ion-content>
</ion-view>
</script>
</body>
</html>
<script>
var app = angular.module("myApp", ["ionic"]);
app.config(function($stateProvider,$urlRouterProvider) {
$stateProvider
.state("home", {
templateUrl: "home.html"
})
.state("music", {
templateUrl: "music.html"
});
})
.controller("myCtrl",function($scope,$state){
$state.go("home");
});
</script>
11. 定制视图切换方向 : nav-direction
使用nav-direction指令声明视图转场时的切换方向:
<any ui-sref=".." nav-direction="..">...</any>
目前支持的选项有:- forward - 新视图从右向左进入
- back - 新视图从左向右进入
- enter -
- exit -
- swap -
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no,width=device-width,height=device-height">
<script src="../../lib/js/ionic.bundle.min.js"></script>
<link rel="stylesheet" type="text/css" href="../../lib/css/ionic.min.css">
</head>
<body ng-controller="myCtrl">
<!--导航框架之导航栏-->
<ion-nav-bar class="bar-positive">
</ion-nav-bar>
<!--导航框架之导航视图-->
<ion-nav-view></ion-nav-view>
<script id="home.html" type="text/ng-template">
<!--导航框架之模板视图-->
<ion-view view-title="Home">
<ion-content>
<ion-list>
<ion-item ui-sref="music" class="item-icon-right" nav-direction="swap">
Go to music page!
<i class="icon ion-ios-arrow-right"></i>
</ion-item>
</ion-list>
</ion-content>
</ion-view>
</script>
<script id="music.html" type="text/ng-template">
<!-- The title of the ion-view will be shown on the navbar -->
<ion-view view-title="Music">
<ion-content>
<ion-list>
<ion-item ui-sref="home" class="item-icon-right" nav-direction="forward">
Go to home page!
<i class="icon ion-ios-arrow-right"></i>
</ion-item>
</ion-list>
</ion-content>
</ion-view>
</script>
</body>
</html>
<script>
var app = angular.module("myApp", ["ionic"]);
app.config(function($stateProvider,$urlRouterProvider) {
$stateProvider
.state("home", {
templateUrl: "home.html"
})
.state("music", {
templateUrl: "music.html"
});
})
.controller("myCtrl",function($scope,$state){
$state.go("home");
});
</script>
12.导航栏脚本接口 : $ionicNavBarDelegate
服务$ionicNavBarDelegate提供了控制导航栏的脚本接口:
- align([direction]) - 标题对齐方式。
- showBackButton([show]) - 是否显示回退按钮
- showBar(show) - 是否显示导航栏
- title(title) - 设置导航栏标题
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no,width=device-width,height=device-height">
<script src="../../lib/js/ionic.bundle.min.js"></script>
<link rel="stylesheet" type="text/css" href="../../lib/css/ionic.min.css">
</head>
<body ng-controller="myCtrl">
<!--导航框架之导航栏-->
<ion-nav-bar class="bar-positive">
<ion-nav-back-button></ion-nav-back-button>
</ion-nav-bar>
<!--导航框架之导航视图-->
<ion-nav-view></ion-nav-view>
<script id="home.html" type="text/ng-template">
<!--导航框架之模板视图-->
<ion-view view-title="Home">
<ion-content>
<ion-list>
<ion-item ui-sref="music" class="item-icon-right">
Go to music page!
<i class="icon ion-chevron-right"></i>
</ion-item>
<ion-item class="item-divider">$ionicNavBarDelegate</ion-item>
<ion-toggle ng-model="flag.shouldSetTitle">title()</ion-toggle>
<ion-toggle ng-model="flag.shouldShowBar">showBar()</ion-toggle>
</ion-list>
</ion-content>
</ion-view>
</script>
<script id="music.html" type="text/ng-template">
<!--导航框架之模板视图-->
<ion-view view-title="Music">
<ion-content class="padding">
<a class="button ion ion-home" ui-sref="home">go home</a>
</ion-content>
</ion-view>
</script>
</body>
</html>
<script>
angular.module("myApp", ["ionic"])
.config(function($stateProvider,$urlRouterProvider) {
$stateProvider
.state("home", {
templateUrl: "home.html"
})
.state("music", {
templateUrl: "music.html"
});
})
.controller("myCtrl",function($scope,$state,$interval,$ionicNavBarDelegate){
$state.go("home");
$scope.flag = {
shouldSetTitle : false,
shouldShowBar : true
};
$scope.$watch("flag.shouldSetTitle",function(nv){
if(nv) $ionicNavBarDelegate.title("<i style='color:red'>▂▃▅▆█</i>");
else $ionicNavBarDelegate.title("Home");
});
$scope.$watch("flag.shouldShowBar",function(nv){
$ionicNavBarDelegate.showBar(nv);
})
})
</script>
13.访问历史 : $ionicHistory
ionic的导航框架会自动维护用户的访问历史栈,我们可以通过服务$ionicHistory管理访问轨迹:
- viewHistory() - 返回视图访问历史数据
- currentView() - 返回当前视图对象
- currentHistoryId() - 返回历史ID
- currentTitle([val]) - 设置或读取当前视图的标题
- backView() - 返回历史栈中前一个视图对象
- backTitle() - 返回历史栈中前一个视图的标题
- forwardView() - 返回历史栈中的下一个视图对象
- currentStateName() - 返回当前所处状态名
- goBack() - 切换到历史栈中前一个视图
- clearHistory() - 请空历史栈
<!DOCTYPE html>
<html ng-app="ezApp">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no,width=device-width,height=device-height">
<script src="ionic.bundle.min.js"></script>
<link rel="stylesheet" type="text/css" href="ionic.min.css">
</head>
<body ng-controller="ezCtrl">
<!--导航框架之导航栏-->
<ion-nav-bar class="bar-positive">
<ion-nav-back-button></ion-nav-back-button>
</ion-nav-bar>
<!--导航框架之导航视图-->
<ion-nav-view></ion-nav-view>
<script id="home.html" type="text/ng-template">
<!--导航框架之模板视图-->
<ion-view view-title="Home">
<ion-content>
<ion-list>
<ion-item ui-sref="music" class="item-icon-right">
Go to music page!
<i class="icon ion-chevron-right"></i>
</ion-item>
<ion-item class="item-divider">$ionicHistory</ion-item>
<ion-item ng-click="show_history($event)">viewHistory()</ion-item>
<ion-toggle ng-model="flag.disableAnimate">nextViewOptions()</ion-toggle>
</ion-list>
</ion-content>
</ion-view>
</script>
<script id="music.html" type="text/ng-template">
<!--导航框架之模板视图-->
<ion-view view-title="Music">
<ion-content class="padding">
<a class="button ion ion-home" ui-sref="home">go home</a>
</ion-content>
</ion-view>
</script>
</body>
</html>
<script>
angular.module("ezApp", ["ionic"])
.config(function($stateProvider,$urlRouterProvider) {
$stateProvider
.state("home", {
templateUrl: "home.html"
})
.state("music", {
templateUrl: "music.html"
});
})
.controller("ezCtrl",function($scope,$state,$ionicPopover,$ionicHistory){
$state.go("home");
$scope.flag = {};
$scope.go_back = function() {
$ionicHistory.goBack();
};
$scope.show_history = function($event){
var h = $ionicHistory.viewHistory(),
hstr = JSON.stringify(h,null," "),
tpl = ["<ion-popover-view>",
"<ion-header-bar>history</ion-header-bar>",
"<ion-content>",
"<pre>",
hstr,
"</pre>",
"</ion-content>",
"</ion-popover-view>"
].join("");
$ionicPopover.fromTemplate(tpl).show($event);
};
$scope.$watch("flag.disableAnimate",function(nv){
$ionicHistory.nextViewOptions({
disableAnimate:nv
})
});
})
</script>
更多推荐
Ionic基础——ionic路由及内联模板
发布评论