详解angularJs模块ui-router之状态嵌套和视图嵌套


Posted in Javascript onApril 28, 2017

状态嵌套的方法

状态可以相互嵌套。有三个嵌套的方法:

  1. 使用“点标记法”,例如:.state('contacts.list', {})
  2. 使用parent属性,指定一个父状态的名称字符串,例如:parent: 'contacts'
  3. 使用parent属性,指定一个父状态对象,例如:parent: contacts(contacts 是一个状态对象)

点标记法

在$stateProvider中可以使用点语法来表示层次结构,下面,contacts.list是contacts的子状态。

$stateProvider
 .state('contacts', {})
 .state('contacts.list', {});

使用parent属性,指定一个父状态的名称字符串

$stateProvider
 .state('contacts', {})
 .state('list', {
  parent: 'contacts'
 });

基于对象的状态

如果你不喜欢使用基于字符串的状态,您还可以使用基于对象的状态。name属性将在状态对象内部设置,在所有的子状态对象中设置parent属性为父状态对象,像下面这样:

var contacts = { 
  name: 'contacts', //mandatory
  templateUrl: 'contacts.html'
}
var contactsList = { 
  name: 'list',   //mandatory
  parent: contacts, //mandatory
  templateUrl: 'contacts.list.html'
}

$stateProvider
 .state(contacts)
 .state(contactsList)

$state.transitionTo(states.contacts);在方法调用和属性比较时可以直接引用状态对象:

$state.current === states.contacts;
$state.includes(states.contacts)

注册状态的顺序

可以以任何顺序和跨模块注册状态,也可以在父状态存在之前注册子状态。一旦父状态被注册,将触发自动排序,然后注册子状态。

状态命名

状态不允许重名,当使用“点标记法”,parent属性被推测出来,但这并不会改变状态的名字;当不使用“点标记法”时,parent属性必须明确指定,但你仍然不能让任何两个状态有相同的名称,例如你不能有两个不同的状态命名为”edit”,即使他们有不同的父状态。

嵌套状态和视图

当应用程序在一个特定的状态 - 当一个状态是活动状态时 - 其所有的父状态都将成为活跃状态。下面例子中,当”contacts.list”是活跃状态时,”contacts”也将隐性成为活跃状态,因为他是”contacts.list”的父状态。

子状态将把其对应的模板加载到父状态对应模板的ui-view中。

$stateProvider
 .state('contacts', {
  templateUrl: 'contacts.html',
  controller: function($scope){
   $scope.contacts = [{ name: 'Alice' }, { name: 'Bob' }];
  }
 })
 .state('contacts.list', {
  templateUrl: 'contacts.list.html'
 });

function MainCtrl($state){
 $state.transitionTo('contacts.list');
}
<!-- index.html -->
<body ng-controller="MainCtrl">
 <div ui-view></div>
</body>
<!-- contacts.html -->
<h1>My Contacts</h1>
<div ui-view></div>
<!-- contacts.list.html -->
<ul>
 <li ng-repeat="contact in contacts">
  <a>{{contact.name}}</a>
 </li>
</ul>

子状态将从父状态继承哪些属性?

子状态将从父母继承以下属性:

  1. 通过解决器解决的依赖注入项
  2. 自定义的data属性

除了这些,没有其他属性继承下来(比如controllers、templates和url等)

继承解决的依赖项

版本 v0.2.0 的新特性

子状态将从父状态继承通过解决器解决的依赖注入项,并且可以重写(overwrite)依赖项,可以将解决依赖项注入子状态的控制器和解决函数中。

$stateProvider.state('parent', {
   resolve:{
     resA: function(){
      return {'value': 'A'};
     }
   },
   controller: function($scope, resA){
     $scope.resA = resA.value;
   }
  })
  .state('parent.child', {
   resolve:{
     // 将父状态的解决依赖项注入到子状态的解决函数中
     resB: function(resA){
      return {'value': resA.value + 'B'};
     }
   },
   // 将父状态的解决依赖项注入到子状态的控制器中
   controller: function($scope, resA, resB){
     $scope.resA2 = resA.value;
     $scope.resB = resB.value;
   }

继承自定义data属性值

子状态将从父状态继承自定义data属性值,并且可以重写(overwrite)data属性值

$stateProvider.state('parent', {
   data:{
     customData1: "Hello",
     customData2: "World!"
   }
  })
  .state('parent.child', {
   data:{
     // customData1 inherited from 'parent'
     // 覆盖了 customData2 的值
     customData2: "UI-Router!"
   }
  });

$rootScope.$on('$stateChangeStart', function(event, toState){ 
  var greeting = toState.data.customData1 + " " + toState.data.customData2;
  console.log(greeting);

  // 'parent'被激活时,输出 "Hello World!"
  // 'parent.child'被激活时,输出 "Hello UI-Router!"
})

Abstract States 抽象状态

一个抽象的状态可以有子状态但不能显式激活,它将被隐性激活当其子状态被激活时。

下面是一些你将可能会使用到抽象状态的示例:

  1. 为所有子状态预提供一个基url
  2. 在父状态中设置template属性,子状态对应的模板将插入到父状态模板中的ui-view(s)中
  3. 通过resolve属性,为所有子状态提供解决依赖项
  4. 通过data属性,为所有子状态或者事件监听函数提供自定义数据
  5. 运行onEnter或onExit函数,这些函数可能在以某种方式修改应用程序。
  6. 上面场景的任意组合

请记住:抽象的状态模板仍然需要<ui-view/>,来让自己的子状态模板插入其中。因此,如果您使用抽象状态只是为了预提供基url、提供解决依赖项或者自定义data、运行onEnter/Exit函数,你任然需要设置template: "<ui-view/>"。

抽象状态使用示例:

为子状态提供一个基url,子状态的url是相对父状态的

$stateProvider
  .state('contacts', {
    abstract: true, 
  url: '/contacts',

    // Note: abstract still needs a ui-view for its children to populate.
    // You can simply add it inline here.
    template: '<ui-view/>'
  })
  .state('contacts.list', {
  // url will become '/contacts/list'
    url: '/list'
  //...more
  })
  .state('contacts.detail', {
  // url will become '/contacts/detail'
    url: '/detail',
  //...more
  })

将子状态模板插入到父状态指定的ui-view中

$stateProvider
  .state('contacts', {
    abstract: true,
    templateURL: 'contacts.html'
  )
  .state('contacts.list', {
    // loaded into ui-view of parent's template
    templateUrl: 'contacts.list.html'
  })
  .state('contacts.detail', {
    // loaded into ui-view of parent's template
    templateUrl: 'contacts.detail.html'
  })
<!-- contacts.html -->
<h1>Contacts Page</h1>
<div ui-view></div>

完整示例

$stateProvider
  .state('contacts', {
    abstract: true,
    url: '/contacts',
    templateUrl: 'contacts.html',
    controller: function($scope){
      $scope.contacts = [{ id:0, name: "Alice" }, { id:1, name: "Bob" }];
    }      
  })
  .state('contacts.list', {
    url: '/list',
    templateUrl: 'contacts.list.html'
  })
  .state('contacts.detail', {
    url: '/:id',
    templateUrl: 'contacts.detail.html',
    controller: function($scope, $stateParams){
     $scope.person = $scope.contacts[$stateParams.id];
    }
  })
<!-- contacts.html -->
<h1>Contacts Page</h1>
<div ui-view></div>
<!-- contacts.list.html -->
<ul>
  <li ng-repeat="person in contacts">
    <a ng-href="#/contacts/{{person.id}}" rel="external nofollow" >{{person.name}}</a>
  </li>
</ul>
<!-- contacts.detail.html -->
<h2>{{ person.name }}</h2>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
解决 FireFox 下[使用event很麻烦] 的问题.
Aug 22 Javascript
JS去除字符串的空格增强版(可以去除中间的空格)
Aug 26 Javascript
20款超赞的jQuery插件 Web开发人员必备
Feb 26 Javascript
json2.js的初步学习与了解
Oct 06 Javascript
js实现目录定位正文示例
Nov 14 Javascript
js实现图片从左往右渐变切换效果的方法
Feb 06 Javascript
Bootstrap入门书籍之(零)Bootstrap简介
Feb 17 Javascript
Bootstrap编写一个同时适用于PC、平板、手机的登陆页面
Jun 30 Javascript
vue 数组和对象不能直接赋值情况和解决方法(推荐)
Oct 25 Javascript
如何以Angular的姿势打开Font-Awesome详解
Apr 22 Javascript
解决vue 格式化银行卡(信用卡)每4位一个符号隔断的问题
Sep 14 Javascript
vue使用echarts实现水平柱形图实例
Sep 09 Javascript
vue基于Vue2.0和高德地图的地图组件实例
Apr 28 #Javascript
d3.js实现立体柱图的方法详解
Apr 28 #Javascript
JS基于正则表达式的替换操作(replace)用法示例
Apr 28 #Javascript
vue调用高德地图实例代码
Apr 28 #Javascript
vue省市区三联动下拉选择组件的实现
Apr 28 #Javascript
AngulaJS路由 ui-router 传参实例
Apr 28 #Javascript
Angular.Js之Scope作用域的学习教程
Apr 27 #Javascript
You might like
PHP以指定字段为索引返回数据库所取的数据数组
2013/06/30 PHP
在 Laravel 中 “规范” 的开发短信验证码发送功能
2017/10/26 PHP
js中使用DOM复制(克隆)指定节点名数据到新的XML文件中的代码
2011/07/27 Javascript
jQuery(非HTML5)可编辑表格实现代码
2012/12/11 Javascript
JS实现仿新浪微博发布内容为空时提示功能代码
2015/08/19 Javascript
javascript实现五星评分功能
2015/11/10 Javascript
直接拿来用的页面跳转进度条JS实现
2016/01/06 Javascript
Zero Clipboard实现浏览器复制到剪贴板的方法(多个复制按钮)
2016/03/24 Javascript
js实现的万能flv网页播放器代码
2016/04/30 Javascript
浅析JS获取url中的参数实例代码
2016/06/14 Javascript
AngularJS  ng-table插件设置排序
2016/09/21 Javascript
利用js来实现缩略语列表、文献来源链接和快捷键列表
2016/12/16 Javascript
AngularJS 应用模块化的使用
2018/04/04 Javascript
浅谈Vue组件及组件的注册方法
2018/08/24 Javascript
vue-resource post数据时碰到Django csrf问题的解决
2020/03/13 Javascript
在Vue.js中使用TypeScript的方法
2020/03/19 Javascript
JQuery使用数组遍历跳出each循环
2020/09/01 jQuery
快速解决element的autofocus失效问题
2020/09/08 Javascript
vue使用transition组件动画效果的实例代码
2021/01/28 Vue.js
python开启多个子进程并行运行的方法
2015/04/18 Python
通过Python爬虫代理IP快速增加博客阅读量
2016/12/14 Python
python绘制已知点的坐标的直线实例
2019/07/04 Python
python openCV获取人脸部分并存储功能
2019/08/28 Python
简单了解Pandas缺失值处理方法
2019/11/16 Python
python3 googletrans超时报错问题及翻译工具优化方案 附源码
2020/12/23 Python
全球酒店预订网站:Hotels.com
2016/08/10 全球购物
美国购买当代和现代家具网站:MODTEMPO
2018/07/20 全球购物
Funko官方商店:源自美国,畅销全球搪胶收藏玩偶
2018/09/15 全球购物
使用索引(Index)有哪些需要考虑的因素
2016/10/19 面试题
期末总结的个人自我评价
2013/11/02 职场文书
致接力运动员广播稿
2014/02/17 职场文书
市场营销毕业求职信
2014/08/07 职场文书
市委召开党的群众路线教育实践活动总结大会报告
2014/10/21 职场文书
学生会干部任命书
2015/09/21 职场文书
2016年“七一建党节”广播稿
2015/12/18 职场文书
SQL之各种join小结详细讲解
2021/08/04 MySQL