本篇接着上一篇 angular的uiRouter服务学习(2) 继续讲解uiRouter的用法

本篇主要讲解uiRouter的多个命名的视图

我们可以给ui-view元素添加ui-view的值来给它命名,这样,一个视图模板里就可以有多个ui-view标签.

比如下面这个应用,它需要动态的填充一个图表,图表里有一些表格数据,筛选项,等:

给视图命名,需要在状态里定义views属性. views的属性值为一个对象.

views属性会覆盖template属性:

如果给状态定义了views属性,那么状态的template,templateUrl,templateProvider将会被无视掉. 考虑这种场景: 一个父视图模板,里面需要包含多个不同的视图. 在这种情况下,可以定义一个抽象状态来充当父状态,然后在子状态里定义views属性.

栗子-name匹配:

views对象里的属性名应该和ui-view元素里面的值所对应,像下面这样:

html:

<div>
<a href="report">查看视图</a>
<div ui-view></div>
<div ui-view="filters"></div>
<div ui-view="tabledata"></div>
<div ui-view="graph"></div>
</div>

js:

var named = angular.module('namedView',['ui.router']);

var report = {
name:'report',
url:'/report',
views:{
'filters':{
templateUrl:'report-filters.html',
controller:function($scope){
$scope.title="我是filters的内容"
}
},
'tabledata':{
templateUrl:'report-table.html',
controller:function($scope){
$scope.title="我是table的内容"
}
},
'graph':{
templateUrl:'report-graph.html',
controller:function($scope){
$scope.title="我是graph的内容"
}
}
}
}; named.config(function($locationProvider,$stateProvider){
$locationProvider.html5Mode({enabled:true}).hashPrefix('!');
$stateProvider.state(report)
});

report-filters.html,report-graph.html,report-table.html:

<h3>{{title}}</h3>

点击'查看视图'激活report状态:

可以看到,report状态被激活后,它有三个ui-view,不同的ui-view有不同的名字,然后通过定义状态的views属性来分别给三个ui-view定义templateUrl,controller.

视图名-相对名字和绝对名字:

views对象的视图名,有两种取法,一种是相对名字,一种是绝对名字.刚才我们看到的例子是绝对名字.如果是相对名字的话,要符合 viewname@statename 这种格式. 其中,viewname就是视图中ui-view属性值; statename是状态名. 连起来就是:在statename状态下,寻找ui-view属性值为对应viewname的元素.

还需要注意一点,viewname可以使用'-'分割的名字,但和指令不同,在js代码里不需要把'-'转换成驼峰命名的格式,而是保持'-'分割的名字就可以了.

比如上面的例子,我们可以把它写成相对名字:

views:{
'filters@':{
...
}
},
'tabledata@':{
...
}
},
'graph@':{
...
}
}
}

这样,视图名就变成了相对名字,这里statename为空,表示根状态,也就是起始html页面.

相对名字可以做一些很强大的视图匹配.比如下面这样一个例子:

named-views.html:

<div>
<a href="report">查看视图</a>
<a href="report/detail">查看子视图</a>
<div ui-view>没有ui-view值</div>
<div ui-view="aaa">ui-view值为aaa</div>
</div>

js:

var named = angular.module('namedView',['ui.router']);
var report = {
name:'report',
url:'/report',
templateUrl:'report.html'
};
var detail = {
name:'report.detail',
url:'/detail',
parent:'report',
views:{
//绝对名字:在父状态的template(也就是report.html)里寻找对应名字为'aaa'的ui-view元素
'aaa':{
templateUrl:'aaa.html'
},

//绝对名字:在父状态的template(也就是report.html)里寻找没有名字的ui-view元素
'':{
templateUrl:'report.detail.html'
},

/*
'aaa@report':{
templateUrl:'aaa.html'
},
'@report':{
templateUrl:'report.detail.html'
},*/

//相对名字:在report.detail状态里寻找对应名字为'bbb'的ui-view元素
'bbb@report.detail':{
templateUrl:'bbb.html'
},
//相对名字:在report.detail状态里寻找对应没有名字的ui-view元素
'@report.detail':{
templateUrl:'no-name.html'
},

//相对名字:在report状态里寻找对应名字为'bbb'的ui-view元素
'bbb@report':{
templateUrl:'bbb2.html'
},
//相对名字:在根状态(named-views.html)里寻找对应名字为'aaa'的ui-view元素
'aaa@':{
templateUrl:'aaa2.html'
},

//相对名字:在根状态(named-views.html)里寻找没有名字的ui-view元素.
//需要特别注意:这里等于是在子状态里定义了父状态的里ui-view,要这样写的话,最开始的两段绝对名字'aaa'和'',就必须改成下面注释的两段相对名字'aaa@report'和'bbb@report'.
//否则会造成错误.
/*
'@':{
templateUrl:'report.html'
}*/
}
}; named.config(function($locationProvider,$stateProvider){
$locationProvider.html5Mode({enabled:true}).hashPrefix('!');
$stateProvider.state(report).state(detail)
});

report.html:

<h1>report.html:</h1>
<div>
<h2>ui-view值为空的内容:</h2>
<div ui-view></div>
</div>
<div>
<h2>ui-view值为'aaa'的内容:</h2>
<div ui-view="aaa"></div>
</div>
<div>
<h2>ui-view值为'bbb'的内容:</h2>
<div ui-view="bbb"></div>
</div>

report.detail.html:

<h3>report.detail.html:</h3>
<div>
<h4>ui-view值为空的内容:</h4>
<div ui-view></div>
</div>
<div>
<h4>ui-view值为'bbb'的内容:</h4>
<div ui-view="bbb"></div>
</div>

aaa.html:

<h3>aaa.html:</h3>

bbb.html:

<h5>bbb.html</h5>

aaa2.html:

<h1>aaa2.html:</h1>

bbb2.html:

<h3>bbb2.html</h3>

no-name.html:

<h5>no-name.html</h5>

点击'查看视图':

点击'查看子视图':

下面分析一下视图的加载:

1.当进入report状态时,会用report.html来填充named-views.html里面的ui-view元素. (ui-view="aaa")不会被填充

2.进入report状态的子状态:report.detail状态.

  (1)'aaa': 绝对名字,在父状态的视图模板里寻找对应名字为'aaa'的ui-view元素. 然后使用'aaa.html'来填充它.

  (2)'': 绝对名字,在父状态的视图模板里寻找没有名字的ui-view元素.然后使用'report.detail.html'来填充它.

  (3)'aaa@report': 相对名字,在report状态里寻找对应名字为'aaa'的ui-view元素. 然后使用'aaa.html'来填充它.

  (4)'@report': 相对名字,在report状态里寻找没有名字的ui-view元素.然后使用'report.detail.html'来填充它.

* 注意,(1)(2)和(3)(4),一个是绝对,一个是相对,但其实都是在report状态里寻找.它们两者的区别最后会说到.

  (5)'bbb@report.detail': 相对名字,在report.detail状态里寻找对应名字为'bbb'的ui-view元素.然后使用'bbb.html'来填充它.

  (6)'@report.detail': 相对名字,在report.detail状态里寻找没有名字的ui-view元素.然后使用no-name.html来填充它.

  (7)'bbb@report': 相对名字,在report状态里寻找对应名字为'bbb'的ui-view元素,然后使用'bbb2.html'来填充它.

  (8)'aaa@': 相对名字,@后面为空,就表示在根状态(也就是named-views.html)里寻找对应名字为aaa的ui-view元素,然后使用'aaa2.html'来填充它

  (9)'@': 相对名字, 表示在根状态(也就是named-views.html)里寻找没有名字的ui-view元素,然后使用'report.html'来填充它.

  (9)的填充方式,和1的填充,从视图匹配的角度来说,是完全一致的,都是在named-views.html里寻找没有名字的ui-view元素,然后用同一个模板来填充它.但是,从使用的角度来说,他们是不同的.

  就拿这个栗子来说: 我这里是把'@'给注释掉了,因为一旦使用了'@',那么(1)(2)'aaa'和''这两个绝对名字,会找不到他们父状态的视图模板.因为他们父状态的视图模板是通过相对名字来定义的.这个时候,如果要用'@',就必须使用(3)(4)'aaa@report'和'@report'.

  *总结来说,绝对名字和相对名字,在一个状态里最好不要混用.

完整代码:https://github.com/OOP-Code-Bunny/angular/tree/master/uiRouter

参考原文:https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views

angular的uiRouter服务学习(3)的更多相关文章

  1. angular的uiRouter服务学习(4)

    本篇接着上一篇angular的uiRouter服务学习(3)继续讲解uiRouter的用法 本篇主要讲解uiRouter的url路由 大多数情况下,状态是和url相关联的: 当url改变,激活对应的状 ...

  2. angular的uiRouter服务学习(2)

    本篇接着上一篇 angular的uiRouter服务学习(1) 继续讲解uiRouter的用法 本篇主要讲解uiRouter的嵌套状态&嵌套视图 嵌套状态的方法: 状态和状态之间可以互相嵌套, ...

  3. angular的uiRouter服务学习(1)

    angular有内置的路由服务$route:angular -- $route API翻译 使用$route可以帮助实现路由的切换,视图的改变,但是这个内置的$route只包含了基本的功能,在很多场合 ...

  4. angular的uiRouter服务学习(5) --- $state.includes()方法

    $state.includes方法用于判断当前激活状态是否是指定的状态或者是指定状态的子状态. $state.includes(stateOrName,params,options) $state.i ...

  5. Angular.js之服务与自定义服务学习笔记

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. 成为优秀Angular开发者所需要学习的19件事

    一款to-do app基本等同于前端开发的"Hello world".虽然涵盖了创建应用程序的CRUD方面,但它通常只涉及那些框架或库也能做到的皮毛而已. Angular看起来似乎 ...

  7. angular利用ui-router登录检查

    angular利用ui-router登录检查 SAP都会有这个问题,session过期或者页面被刷新的情况下应该进入登录页. 监听ui-router的satte事件可以实现当state切换的时候检查登 ...

  8. angular的splitter案例学习

    angular的splitter案例学习,都有注释了,作为自己的备忘. <!DOCTYPE html> <html ng-app="APP"> <he ...

  9. 介绍Angular的注入服务

    其实angular的注入服务是挺复杂的,目前看源码也只看懂了一半,为了不误导大家,我也不讲敢讲太复杂,怕自己都理解错了. 首先我们要知道angular的三种注入方式: 第一种:inference va ...

随机推荐

  1. scala map操作 简单总结

    在函数式编程中有一个核心的概念之一是转换,所以大部份支持函数式编程语言,都支持一种叫map()的动作,这个动作是可以帮你把某个容器的内容,套上一些动作之后,变成另一个新的容器. 现在我们考虑如何用Op ...

  2. 架构-到底什么时候该使用MQ【转】

    点击:<查看原文> 一.缘起 一切脱离业务的架构设计与新技术引入都是耍流氓. 引入一个技术之前,首先应该解答的问题是,这个技术解决什么问题. 就像微服务分层架构之前,应该首先回答,为什么要 ...

  3. UCCI协议[转]

    象棋百科全书 中国象棋电脑应用规范(五) 中国象棋通用引擎协议 版本:3.0 象棋百科全书网 (webmaster@xqbase.com) 2004年12月初稿,2007年11月修订 一.概述 中国象 ...

  4. Redis学习之路(008)- Redis C语言客户端库hiredis文档翻译

    Hiredis是Redis数据库一个轻量的C语言客户端库. 之所以轻量是由于它只是简单的提供了对redis操作语句支持的接口,并没有实现具体的操作语句的功能.但正是由于这种设计使我们只要熟悉了通用的r ...

  5. VS2010编译Boost 1.56

    (1)首先下载源代码:http://softlayer-dal.dl.sourceforge.net/project/boost/boost/1.56.0/boost_1_56_0.zip 解压到某个 ...

  6. POJ 3683 Priest John's Busiest Day (2-SAT)

    Priest John's Busiest Day Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6900   Accept ...

  7. 【C语言】练习1-21

    题目来源:<The C programming language>中的习题 练习1-21:编写程序entab,将空格串替换为最好数量的制表符和空格,但要保持单词之间的间隔不变. 思路: 对 ...

  8. SQLAlchemy(1) -- Python的SQLAlchemy和ORM

    Python的SQLAlchemy和ORM(object-relational mapping:对象关系映射) web编程中有一项常规任务就是创建一个有效的后台数据库.以前,程序员是通过写sql语句, ...

  9. java 和 C++ Socket通信(java作为服务端server,C++作为客户端client,解决中文乱码问题GBK和UTF8)

    原文链接: http://www.cnblogs.com/kenkofox/archive/2010/04/25/1719649.html 代码: http://files.cnblogs.com/k ...

  10. 10.翻译:EF基础系列---EF中的持久性

    原文链接:http://www.entityframeworktutorial.net/EntityFramework4.3/persistence-in-entity-framework.aspx ...