angular的uiRouter服务学习(2)
本篇接着上一篇 angular的uiRouter服务学习(1) 继续讲解uiRouter的用法
本篇主要讲解uiRouter的嵌套状态&嵌套视图
嵌套状态的方法:
状态和状态之间可以互相嵌套,状态的嵌套共有以下几种方式:
1.使用'.state()'进行嵌套. 比如 .state('contact',{}).state('contact.list',{})
2.使用 ui-router.stateHelper 来创建状态嵌套树. 这种方式需要另外引入依赖,所以很少被使用.也就不具体详解了
3.定义状态的'parent'属性,属性值是一个字符串,就是父状态的名字.比如 {parent:'contacts'}
4.定义状态的'parent'属性,属性值是一个对象,对象就是父状态对象.比如 {parent:contacts}
使用.state()来创建嵌套状态:
可以对$stateProvider使用.state()来指定状态的嵌套继承,比如下面的例子:contacts.list就是contacts的一个子状态:
html:
<div>
<a href="contacts">查看视图</a>
<a href="contacts/list">查看嵌套视图</a>
<ui-view>点击链接后内容会被加载在这里</ui-view>
</div>
js
var nest = angular.module('nest',['ui.router']);
nest.config(function($stateProvider){
$stateProvider.state('contacts',{
url:'/contacts',
templateUrl:'contacts.html'
}).state('contacts.list',{
url:'/list',
templateUrl:'contacts.list.html'
})
});
contacts.html
<h4>联系人列表:</h4>
<ui-view></ui-view>
contacts.list.html
<p>我是contacts.list的内容</p>
*需要注意的是,子状态的url是以父状态的url为baseUrl的.所以这里子状态的url应该是'/contacts/list'
定义状态的'parent'属性,属性值是一个字符串:
可以通过状态的parent属性来指定它的父状态.
js:
nest.config(function($stateProvider){
$stateProvider.state('contacts',{
url:'/contacts',
templateUrl:'contacts.html'
}).state('list',{
url:'/list',
templateUrl:'contacts.list.html',
parent:'contacts'
})
});
这种方式和上一中方式的区别在于,子状态不需要使用 '父状态.子状态' 这种格式.但是需要指定子状态的parent属性为'父状态名'
基于对象的状态实现嵌套状态:
如果你不喜欢上面说到的两种方式,那么还可以使用基于对象的状态: 为状态添加一个name属性,然后给子状态设置parent属性为父状态对象.
需要注意的是,使用这种方式,子状态的name属性命名规则必须和.state()方法一样,按照'父状态.子状态'的格式来命名
var contacts = {
name:'parent', //特意不取名叫'contacts'
url:'/contacts',
templateUrl:'contacts.html'
};
var list = {
name:'parent.child',
url:'/list',
templateUrl:'contacts.list.html',
parent:contacts
};
nest.config(function($locationProvider,$stateProvider){
$stateProvider.state(contacts).state(list);
});
状态的注册顺序:
状态的注册顺序无关紧要,你也可以先注册子状态再注册父状态.它会被放在队列里直到父状态被注册的时候才被注册.
父状态必须存在:
如果你只注册了一个子状态,比如contacts.list, 你就必须定义一个叫做contacts的父状态,(定义先后顺序无所谓,但一定要定义),否则的话,将不会有状态被注册.contacts.list这个状态会被放在队列中,直到contacts状态被定义. 如果你不定义父状态,也不会有任何的报错.所以需要注意,为了让子状态生效,必须定义父状态.
状态取名规则:
没有任何两个状态可以拥有相同的名字. 当使用.state()来创建嵌套状态的时候,父状态没有被指定,而是通过推断得到的. 当不使用.state()来创建嵌套状态的时候,parent属性必须被定义,但即使是两个拥有不同父状态的子状态,你依然不能给它们取相同的名字.
状态和视图的嵌套:
当应用处于一个特定的状态时(也就是某个状态被激活时),这个状态的所有祖先状态也都被激活了. 比如上面的所有例子: 当 'contacts.list' 状态被激活,'contacts' 状态也被隐式的激活了,因为它是 'contacts.list'的父状态.
子状态会把它的视图模板加载到父状态的模板的 ui-view 元素中去.
比如上面的这些例子,只要<a href="contacts/list">查看嵌套视图</a>被点击,contacts.list状态被激活,contacts状态也会被隐式的激活.
子状态从父状态继承了什么?
子状态从父状态继承了以下两项:
- 父状态中通过resolve定义的依赖
- 父状态自定义的data属性
其余的,比如控制器,模板,url,等都不会被继承...
resolve继承的栗子:
核心代码:
var contacts = {
name:'parent',
url:'/contacts',
templateUrl:'contacts.html',
resolve:{
resA:function(){
return {value:'A'}
}
},
controller:function($scope,resA){
$scope.a = resA.value
}
};
var list = {
name:'parent.child',
url:'/list',
templateUrl:'contacts.list.html',
parent:contacts,
resolve:{
resB:function(resA){
return {value:resA.value+'B'}
}
},
controller:function($scope,resB){
$scope.b = resB.value
}
};
nest.config(function($locationProvider,$stateProvider){
$locationProvider.html5Mode({enabled:true}).hashPrefix('!');
$stateProvider.state(contacts).state(list);
});
contacts.html:
{{a}} //A
contacts.list.html:
{{a}} //A
{{b}} //AB
可以看到,contacts.list子状态继承了contacts父状态里resolve的依赖'resA'
需要注意: 如果你想在子状态实例化之前解析完父状态的resolve项里的某个promise依赖,那么,这个promise依赖必须被注入到子状态里去.
data继承的栗子:
核心代码:
var contacts = {
name:'parent',
url:'/contacts',
templateUrl:'contacts.html',
data:{
dataA:'a',
dataB:'b'
},
controller:function($scope,$state){
$scope.a = $state.current.data.dataA;
}
};
var list = {
name:'parent.child',
url:'/list',
templateUrl:'contacts.list.html',
parent:contacts,
controller:function($scope,$state){
$scope.a = $state.current.data.dataA;
$scope.b = $state.current.data.dataB;
}
};
nest.config(function($locationProvider,$stateProvider){
$locationProvider.html5Mode({enabled:true}).hashPrefix('!');
$stateProvider.state(contacts).state(list);
});
contacts.html:
{{a}} //a
contacts.list.html:
{{a}} //a
{{b}} //b
可以看到,父状态的data属性都被子状态继承了
状态的继承是基于视图的继承的
注意,scope作用域的继承和状态的继承无关,它只和视图之间的嵌套关系有关.
很有可能有这种情况: 子状态的视图不仅用于被填充到父状态的视图中,也可能被填充到很多其他地方.在这种情况下.只有被填充到父状态的子状态的视图,才能继承父状态的scope,这种继承只是angular本身的scope继承机制,和状态继承机制是无关的.所以被填充到其他地方的视图是不能访问到父状态的scope的.
抽象状态
一个抽象状态它拥有自己的子状态,但是它不能激活自己. 它只能当子状态被激活的时候,隐式的被激活.
如果要让一个状态成为抽象状态,需要给它设置abstract属性为true
下面是几种抽象状态常用的场合:
- 给子状态们的url提供一个基础url.
- 插入带有ui-view(s)的视图模板,显示子状态们通用的内容,而ui-view部分供各个子状态不同的视图模板来填充.
- 可以给视图添加一个控制器
- 另外,这样也可以把$scope对象继承给子状态.但是注意,就如同上一点所说的,这是通过angular的scope的视图继承机制实现的,不是状态继承
- 通过data属性,给子状态们提供数据.
- 通过resolve属性,给子状态们提供依赖.
- 通过触发onEnter和onExit回调,来处理一些事情.
- 以上几种情况的混合.
注意: 抽象状态也需要带有<ui-view>元素来让子状态视图填充,所以,如果你创建抽象状态是为了给子状态提供基础url,提供resolve依赖,data数据,或者调用onEnter和onExit回调,那么你需要在template属性中设置视图模板为:''<ui-view/>".
下面简单举几个栗子:
栗子1:给子状态们的url提供一个基础url.
html:
<div>
<a href="contacts">查看视图</a>
<a href="contacts/list">查看嵌套视图1</a>
<a href="contacts/detail">查看嵌套视图2</a>
<ui-view>点击链接后内容会被加载在这里</ui-view>
</div>
js:
var contacts = {
abstract:true,
name:'parent',
url:'/contacts',
template:'<ui-view/>'
};
var list = {
name:'parent.child',
url:'/list',
templateUrl:'contacts.list.html',
parent:contacts
};
var detail = {
name:'parent.detail',
url:'/detail',
templateUrl:'contacts.detail.html',
parent:contacts
};
nest.config(function($locationProvider,$stateProvider){
$locationProvider.html5Mode({enabled:true}).hashPrefix('!');
$stateProvider.state(contacts).state(list).state(detail);
});
contacts.list.html:
<p>我是contacts.detail</p>
contacts.detail.html:
<p>我是contacts.detail</p>
当url变为'contacts/list'和'contacts/detail'的时候,会激活相应的状态
------------------------------------------------------------------------------------------------------------------------------------------
栗子2: 父状态插入带有ui-view(s)的视图模板,显示子状态们通用的内容,而ui-view部分供各个子状态不同的视图模板来填充.
html同上.
js:
var contacts = {
abstract:true,
name:'parent',
url:'/contacts',
templateUrl:'contacts.html'
};
var list = {
name:'parent.child',
url:'/list',
templateUrl:'contacts.list.html',
parent:contacts
};
var detail = {
name:'parent.detail',
url:'/detail',
templateUrl:'contacts.detail.html',
parent:contacts
};
nest.config(function($locationProvider,$stateProvider){
$locationProvider.html5Mode({enabled:true}).hashPrefix('!');
$stateProvider.state(contacts).state(list).state(detail);
});
contacts.html:
<h4>联系人列表:</h4>
<ui-view></ui-view>
无论切换哪个子状态,contacts.html中的<h4>联系人列表:</h4>部分都是通用的.
------------------------------------------------------------------------------------------------------------------------------------------
栗子3: 混合使用
html:
<div>
<a href="contacts">查看视图</a>
<a href="contacts/list">查看嵌套视图1</a>
<ui-view>点击链接后内容会被加载在这里</ui-view>
</div>
js:
var contacts = {
abstract:true,
name:'parent',
url:'/contacts',
templateUrl:'contacts.html',
controller:function($scope){
$scope.contacts = [{id:0,name:'code_bunny'},{id:1,name:'white_bunny'},{id:2,name:'black_bunny'}]
}
};
var list = {
name:'parent.child',
url:'/list',
templateUrl:'contacts.list.html',
parent:contacts
};
var detail = {
name:'parent.detail',
url:'/detail/:id',
templateUrl:'contacts.detail.html',
parent:contacts,
controller:function($scope,$stateParams){
$scope.id = $stateParams.id
}
};
nest.config(function($locationProvider,$stateProvider){
$locationProvider.html5Mode({enabled:true}).hashPrefix('!');
$stateProvider.state(contacts).state(list).state(detail);
});
contacts.html:
<h4>联系人列表:</h4>
<ui-view></ui-view>
contacts.list.html:
<ul>
<li ng-repeat="contact in contacts">
<a href="contacts/detail/{{contact.id}}">{{contact.name}}</a>
</li>
</ul>
contacts.detail.html:
<p>{{contacts[id]['name']}}</p>
完整代码: https://github.com/OOP-Code-Bunny/angular/tree/master/uiRouter
参考网站: https://github.com/angular-ui/ui-router/wiki/Nested-States-%26-Nested-Views
angular的uiRouter服务学习(2)的更多相关文章
- angular的uiRouter服务学习(4)
本篇接着上一篇angular的uiRouter服务学习(3)继续讲解uiRouter的用法 本篇主要讲解uiRouter的url路由 大多数情况下,状态是和url相关联的: 当url改变,激活对应的状 ...
- angular的uiRouter服务学习(3)
本篇接着上一篇 angular的uiRouter服务学习(2) 继续讲解uiRouter的用法 本篇主要讲解uiRouter的多个命名的视图 我们可以给ui-view元素添加ui-view的值来给它命 ...
- angular的uiRouter服务学习(1)
angular有内置的路由服务$route:angular -- $route API翻译 使用$route可以帮助实现路由的切换,视图的改变,但是这个内置的$route只包含了基本的功能,在很多场合 ...
- angular的uiRouter服务学习(5) --- $state.includes()方法
$state.includes方法用于判断当前激活状态是否是指定的状态或者是指定状态的子状态. $state.includes(stateOrName,params,options) $state.i ...
- Angular.js之服务与自定义服务学习笔记
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 成为优秀Angular开发者所需要学习的19件事
一款to-do app基本等同于前端开发的"Hello world".虽然涵盖了创建应用程序的CRUD方面,但它通常只涉及那些框架或库也能做到的皮毛而已. Angular看起来似乎 ...
- angular利用ui-router登录检查
angular利用ui-router登录检查 SAP都会有这个问题,session过期或者页面被刷新的情况下应该进入登录页. 监听ui-router的satte事件可以实现当state切换的时候检查登 ...
- angular的splitter案例学习
angular的splitter案例学习,都有注释了,作为自己的备忘. <!DOCTYPE html> <html ng-app="APP"> <he ...
- 介绍Angular的注入服务
其实angular的注入服务是挺复杂的,目前看源码也只看懂了一半,为了不误导大家,我也不讲敢讲太复杂,怕自己都理解错了. 首先我们要知道angular的三种注入方式: 第一种:inference va ...
随机推荐
- ISCSI测试
Initiator为应用客户端,服务端Target包括设备服务器端和队列管理两部分.服务端两种共享方式:1.在服务端共享分区2.在服务端以文件方式作为共享设备共享出来 构建ISCSI网络存储 测试环境 ...
- Visual Studio 2015新添加宏
这个宏是类似环境变量,比如$(ProjectDir) $(SolutionDir),这样的,我需要新添加一个变量宏,但是VS的GUI上貌似找不到新的变量的设置,但是Qt的VS插件可以设置$(QTDIR ...
- 【php页面表单提交】form校验后再提交,非ajax提交
form表单校验后,在执行提交动作: <form method="post" action="{:U('Custom/addmsg')}" id=&quo ...
- Cordova笔记(一)
跨平台的PhoneGap被Adobe收购,改名为Cordova,现在是Apache下的一款开源软件.网上能找到的关于PhoneGap的教程有些方法已不适用,在学习使用最新版的Cordova时有些问题需 ...
- PHPNow升级PHP版本为5.3.5的方法(转)
PHPNow升级PHP版本为5.3.5的方法 原文:http://sharebar.org/1142.html 在WIN上有时候需要测试一些PHP程序,又不会自行独立配置环境,那么PHPNow是非常好 ...
- XML 特殊字符处理
在XML中,有一些符号作为XML 的标记符号,一些特定情况下,属性值必须带有这些特殊符号. 下面主要是讲解一些常用的特殊符号的处理 例一: 双引号的使用. 双引号作为XML 属性值的开始结束符号,因此 ...
- Git 查看提交历史(分布式版本控制系统)
1.查看提交历史 在提交了若干更新,又或者克隆了某个项目之后,你也许想回顾下提交历史.完成这个任务最简单而又有效的工具是 git log 命令. $ git log commit ca82a6dff8 ...
- App Icon Gear App 图标制作工具
1.App Icon Gear 简介 App Icon Gear(原名 AppIconMaker)不仅可以创建 App 图标.启动图 LaunchImage,还可以生成自定义尺寸的图标集(Image ...
- 如何从40亿整数中找到不存在的一个 webservice Asp.Net Core 轻松学-10分钟使用EFCore连接MSSQL数据库 WPF实战案例-打印 RabbitMQ与.net core(五) topic类型 与 headers类型 的Exchange
如何从40亿整数中找到不存在的一个 前言 给定一个最多包含40亿个随机排列的32位的顺序整数的顺序文件,找出一个不在文件中的32位整数.(在文件中至少确实一个这样的数-为什么?).在具有足够内存的情况 ...
- 【LeetCode-面试算法经典-Java实现】【059-Spiral Matrix II(螺旋矩阵II)】
[059-Spiral Matrix II(螺旋矩阵II)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 Given an integer n, generate a ...