详解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 相关文章推荐
使两个iframe的高度与内容自适应,且相等
Nov 20 Javascript
自制轻量级仿jQuery.boxy对话框插件代码
Oct 26 Javascript
JavaScript设计模式之原型模式(Object.create与prototype)介绍
Dec 28 Javascript
jquery ezUI 双击行记录弹窗查看明细的实现方法
Jun 01 Javascript
BootStrap glyphicon图标无法显示的解决方法
Sep 06 Javascript
JavaScript用构造函数如何获取变量的类型名
Dec 23 Javascript
微信小程序 Canvas增强组件实例详解及源码分享
Jan 04 Javascript
JS实现手写parseInt的方法示例
Sep 24 Javascript
vue3.0 CLI - 2.4 - 新组件 Forms.vue 中学习表单
Sep 14 Javascript
javascript随机变色实例代码
Oct 15 Javascript
react结合bootstrap实现评论功能
May 30 Javascript
js实现贪吃蛇小游戏(加墙)
Jul 31 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网站地图生成类示例
2014/01/13 PHP
PHP OPP机制和模式简介(抽象类、接口和契约式编程)
2014/06/09 PHP
php遍历、读取文件夹中图片并分页显示图片的方法
2016/11/15 PHP
Yii 2.0自带的验证码使用经验分享
2017/06/19 PHP
jQuery 选择器理解
2010/03/16 Javascript
.net,js捕捉文本框回车键事件的小例子(兼容多浏览器)
2013/03/11 Javascript
jquery等待效果示例
2014/05/01 Javascript
常见JS验证脚本汇总
2015/12/01 Javascript
分析js闭包引起的事件注册问题
2016/03/29 Javascript
json的使用小结
2016/06/08 Javascript
Vue.js基础指令实例讲解(各种数据绑定、表单渲染大总结)
2017/07/03 Javascript
[js高手之路]HTML标签解释成DOM节点的实现方法
2017/08/31 Javascript
使用cookie绕过验证码登录的实现代码
2017/10/12 Javascript
微信小程序App生命周期详解
2018/01/31 Javascript
JavaScript设计模式之单例模式原理与用法实例分析
2018/07/26 Javascript
Angular8 简单表单验证的实现示例
2020/06/03 Javascript
使用简单工厂模式来进行Python的设计模式编程
2016/03/01 Python
python自定义异常实例详解
2017/07/11 Python
python使用jieba实现中文分词去停用词方法示例
2018/03/11 Python
Django使用paginator插件实现翻页功能的实例
2018/10/24 Python
django之从html页面表单获取输入的数据实例
2020/03/16 Python
python 日志 logging模块详细解析
2020/03/31 Python
浅谈Python中文件夹和python package包的区别
2020/06/01 Python
简单几步用纯CSS3实现3D翻转效果
2019/01/17 HTML / CSS
美国维生素、补充剂、保健食品购物网站:Vitacost
2016/08/05 全球购物
戴尔英国官网:Dell英国
2017/05/27 全球购物
Expedia印度:您的一站式在线旅游网站
2017/08/24 全球购物
英国女性时尚品牌:Apricot
2018/12/04 全球购物
自然健康的概念:Natural Healthy Concepts
2020/01/26 全球购物
CSS实现fullpage.js全屏滚动效果的示例代码
2021/03/24 HTML / CSS
文案策划求职信
2014/03/18 职场文书
重阳节标语大全
2014/10/07 职场文书
2015年共青团工作总结
2015/05/15 职场文书
《认识年月日》教学反思
2016/02/19 职场文书
2016年六一儿童节开幕词
2016/03/04 职场文书
MySQL中IO问题的深入分析与优化
2022/04/02 MySQL