为了获得更详细的答案,我们可以/应该观察源代码并检查文档。让我尝试解释所有三个问题(并引用代码和文档)。
1. 控制器什么时候被实例化?
这里我们可以观察一下代码ui-view
指示:
[$ViewDirective.$inject = \['$state', '$injector', '$uiViewScroll', '$interpolate'\];][1]
控制器相关于views. Those views
,它们定义在 a 内部.state()
as the views
object:
.state('...', {
// The view definition
views : {
'' : {
template: ...
controller: ...
resolve: ..
}
},
resolve: ...
}
所以,无论何时view (the ui-view
)填充了状态视图内部定义的设置,它几乎充当标准但增强的指令.
1)找到模板,
2)解决方案已解决
...
x) 控制器被实例化...
查看目标 (ui-view
指令)可以使用名称,并且可以由层次结构中的不同状态填充。
这可能意味着一个视图中可能有内容(e.g. title), 被定义为parent以及替换为child
// parent
.state('parent', {
views : {
'' : {...} // the main parent view, with ui-view="title"
'title@parent' : { ...} // here we go and fill parent's ui-view="title"
},
...
}
// child
.state('parent.child', {
views : {
'title' : { ...} // here we change the parent's target ui-view="title"
},
...
}
上述状态定义将(每当我们在这两种状态之间转换时) do:
每次我们去的时候都会发生这种情况从父母到孩子 and 从孩子到父母.
2. 在嵌套路由下,所有视图是否共享一个控制器和作用域?
一个简单的答案是NO, 有no共同分享。
实际上,每个控制器 has 它自己的范围,从父视图范围创建的视图。首先是文档:
子状态从父状态继承什么? https://github.com/angular-ui/ui-router/wiki/Nested-States-%26-Nested-Views#what-do-child-states-inherit-from-parent-states
...
仅通过视图层次结构进行范围继承 https://github.com/angular-ui/ui-router/wiki/Nested-States-%26-Nested-Views#scope-inheritance-by-view-hierarchy-only
请记住,如果状态视图是嵌套的,则作用域属性仅沿状态链继承。范围属性的继承与状态的嵌套无关,而与视图(模板)的嵌套有关。
您完全有可能拥有嵌套状态,其模板会在站点内的各个非嵌套位置填充 ui 视图。在这种情况下,您不能期望在子状态视图中访问父状态视图的作用域变量。
所以,每当我们controller
(好吧view带模板、控制器...)注入父母的目标ui-view="..."
它获得继承范围:
newScope = scope.$new();
简而言之,这意味着JS 对象 (e.g. scope.Model = {}
)可以在孩子和家长之间共享。
$scope.Model.id = 1; // will refer to the same id in both parent & child
However,基本 Javascript 类型不是通过引用传递的,因此它们的值不会在作用域之间自动同步:
// set in parent
$scope.id = 1;
// in child after inherted still === 1
$scope.id = 2; // now 2 for a child, different value in parent - still === 1
值得在这里阅读更多有关原型继承的内容:
AngularJS 中的范围原型/原型继承有哪些细微差别? https://stackoverflow.com/q/14049480/1679310
3. 当我切换状态并返回到某个状态时会发生什么 - 是否会实例化另一个控制器?
这取决于。
如果父子视图(记住ui-view="title"
above)被子视图替换,然后重新创建(从孩子到父母的转变)- 这样的控制器将被重新初始化(如上所述)。
但当我们谈论主要父视图 (通常是未命名的),这代表家长 (例如下面带有控制器“ParentMainCtrl”的未命名视图)
.state('parent', {
views : {
'' : { // // the main parent view
controller: 'ParentMainCtrl',
}
'title@parent'
'tooltip@parent'
},
然后我们可以确定这样的控制器不会被重新实例化。它在其所有子级以及父级的一生中都存在(未选择子状态).
要重新加载此视图/控制器,我们必须使用一个选项reload
$state.go(to, 参数, 选项) http://angular-ui.github.io/ui-router/site/#/api/ui.router.state.%24state
...
options 选项对象。选项有:
- ...
-
reload -
{boolean=false}
,如果 true 将强制转换,即使状态或参数没有更改,也称为相同状态的重新加载。它与 reloadOnSearch 不同,因为当您想要在一切都相同(包括搜索参数)时强制重新加载时,您可以使用它。
希望有点帮助。有关更多信息,请查看以下资源:
- 嵌套状态和嵌套视图 https://github.com/angular-ui/ui-router/wiki/Nested-States-%26-Nested-Views
- 多个命名视图 https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views
-
API参考 http://angular-ui.github.io/ui-router/site/#/api/ui.router
-
State.js https://github.com/angular-ui/ui-router/blob/master/sample/app/contacts/contacts.js of 示例应用程序 http://angular-ui.github.io/ui-router/sample/#/ - 我想说的是最好的记录代码ever