学习 ui-router (二): 状态嵌套和视图嵌套

前端之家收集整理的这篇文章主要介绍了学习 ui-router (二): 状态嵌套和视图嵌套前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

转自:http://bubkoo.com/2014/01/01/angular/ui-router/guide/nested-states%20&%20nested-views/


参考原文:https://github.com/angular-ui/ui-router/wiki/Nested-States-%26-Nested-Views

状态嵌套的方法

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

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

标记

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

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

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

     
     
1
2
3
4
5
'list',{
     
     
     
     
parent: 'contacts'
});

基于对象的状态

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

     
     
1
2
3
4
5
6
7
8
9
10
11
12
13
     
     
var contacts = {
name: //mandatory
templateUrl: 'contacts.html'
}
var contactsList = {
name: //mandatory
parent: contacts,153)">'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中。

     
     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    
      
      templateUrl: 
      
      'contacts.html',
     
     
controller: function($scope){
$scope.contacts = [{ name: 'Alice' },{ name: 'Bob' }];
}
})
.state( 'contacts.list.html'
});
function MainCtrl($state){
$state.transitionTo( 'contacts.list');
}
     
     
1
2
3
4
     
     
<!-- index.html -->
<body ng-controller="MainCtrl">
<div ui-view> </div>
</body>
<!-- contacts.html -->
     
     
     
     
<h1>My Contacts </h1>
</div>
     
     
1
2
3
4
5
6
<!-- contacts.list.html -->
     
     
     
     
<ul>
<li ng-repeat="contact in contacts">
<a>{{contact.name}} </a>
</li>
</ul>

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

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

继承解决的依赖项

版本 v0.2.0 的新特性

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

     
     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
     
     
$stateProvider.state( 'parent',{
resolve:{
resA: ){
return { 'value': 'A'};
}
},
controller: $scope,resA){
$scope.resA = resA.value;
}
})
.state( 'parent.child',{
resolve:{
// 将父状态的解决依赖项注入到子状态的解决函数
resB: resA){
'value': resA.value + 'B'};
}
},
// 将父状态的解决依赖项注入到子状态的控制器中
controller: $scope.resA2 = resA.value;
$scope.resB = resB.value;
}

继承自定义data属性

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

     
     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
      
      
      data:{
     
     
     
     
customData1: "Hello",
customData2: "World!"
}
})
.state( data:{
// customData1 inherited from 'parent'
// 覆盖了 customData2 的值
customData2: "UI-Router!"
}
});
$rootScope.$on( '$stateChangeStart',event,toState){
var greeting = toState.data.customData1 + " " + toState.data.customData2;
console.log(greeting);
// 'parent'被激活时,输出 "Hello World!"
// 'parent.child'被激活时,输出 "Hello UI-Router!"
})

Abstract States 抽象状态

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

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

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

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

抽象状态使用示例:

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

     
     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
     
     
$stateProvider
.state( 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( // url will become '/contacts/list'
url: '/list'
//...more
})
.state( 'contacts.detail',153)">// url will become '/contacts/detail'
url: '/detail',
//...more
})

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

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

组合使用示例

完整示例:http://plnkr.co/edit/gmtcE2?p=preview

     
     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
        
      
      url: 
      
              
      
      templateUrl: 
      
              
      
      controller: 
      
      $scope){
     
     
     
     
$scope.contacts = [{ id: 0,name: "Alice" },{ id: 1,153)">"Bob" }];
}
})
.state( url: '/list',153)">'/:id',153)">'contacts.detail.html',$stateParams){
$scope.person = $scope.contacts[$stateParams.id];
}
})
<ul>
     
     
     
     
"person in contacts">
<a ng-href="#/contacts/{{person.id}}">{{person.name}} </a>
</ul>
     
     
1
2
<!-- contacts.detail.html -->
     
     
     
     
<h2>{{ person.name }} </h2>

猜你在找的Angularjs相关文章