我对何时实例化控制器感到困惑。另外,嵌套状态时如何实例化控制器。我可能会感到困惑,如何将范围附加到视图和控制器,也就是说,如果每个视图都有自己的控制器和范围,或者它们共享相同的范围。
有人可以解释何时实例化控制器吗?在嵌套路由下,所有视图是否共享一个控制器和范围?当我切换状态并返回另一个控制器实例化的状态时会发生什么?
以下是我的路线(配置文件):
.config (googleAnalyticsCordovaProvider, $stateProvider, $urlRouterProvider, IdleProvider, KeepaliveProvider) -> $stateProvider .state('app', { url: '/app', abstract: true, templateUrl: 'templates/menu.html', controller: 'AppController' }) .state('app.pincode', { url: '/pincode', views: { menuContent: { templateUrl: 'templates/pincode-yield.html', controller: 'PincodeController' } } }) .state('app.pincode.create', { url: '/create', views: { pincode: { templateUrl: 'templates/pincode-create.html', controller: 'PincodeController' } } }) .state('app.pincode.pincodeLogin', { url: '/login', views: { pincode: { templateUrl: 'templates/pincode-login.html', controller: 'PincodeController' } } }) .state('app.pincode.settings', { url: '/settings', views: { pincode: { templateUrl: 'templates/settings.html', controller: 'PincodeController' } } })
要获得更详细的答案,我们可以/应该观察 源代码 并检查 文档 。让我尝试解释所有三个问题(并从代码和文档中引用)。
1.控制器何时实例化?
在这里,我们可以观察ui-view指令的代码:
ui-view
[$ViewDirective.$inject = \['$state', '$injector', '$uiViewScroll', '$interpolate'\];][1]
控制器与 视图 相关。那些views在内定义.state()为 views 对象的:
views
.state()
.state('...', { // The view definition views : { '' : { template: ... controller: ... resolve: .. } }, resolve: ... }
所以,每当是 视图 (该ui-view)充满的状态视图的内部定义的设置,它的作用几乎作为一个 标准,但增强的指令 。
1)找到模板, 2)解决解析 … x)实例化控制器…
视图目标(ui-view指令)可以使用名称,并且可以由层次结构中的不同状态填充。
这可能意味着,在一个视图 _(例如 title* )_内可能有一个内容,该内容由 父级 定义并且由 子级 替换 *
// 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" }, ... }
上面的状态定义 (无论何时在这两个状态之间进行转换) 都将:
定义的$state.go('parent')-视图(模板,控制器…)'title@parent' : { ...}将被注入目标ui-view="title"并如上所述进行实例化
$state.go('parent')
'title@parent' : { ...}
ui-view="title"
本$state.go('parent.child')-几乎是相同的,只是视图将从子状态/图确定指标采取'title' : { ...}。它将替换和的内容,ui-view="title"并如上所述进行实例化
$state.go('parent.child')
'title' : { ...}
每当我们 从父母到孩子 以及 从孩子到父母 去做时,都会发生这种情况。
2.在嵌套路由下,所有视图是否共享一个控制器和范围?
一个简单的答案是“ 否” , 没有 共同的共享。
实际上, 每个控制器 都有 自己的作用域 ,即从父视图作用域创建的作用域。首先是文档:
儿童作用域从父作用域继承什么? … 仅按视图层次结构的作用域继承 请记住,如果状态的视图是嵌套的,则范围属性仅沿状态链继承。范围属性的继承与状态的嵌套无关,而与视图(模板)的嵌套无关。 完全有可能存在嵌套状态,这些状态的模板会在站点内各个非嵌套位置填充ui视图。在这种情况下,您不能期望在子状态的视图中访问父状态视图的范围变量。
儿童作用域从父作用域继承什么?
…
仅按视图层次结构的作用域继承
请记住,如果状态的视图是嵌套的,则范围属性仅沿状态链继承。范围属性的继承与状态的嵌套无关,而与视图(模板)的嵌套无关。
完全有可能存在嵌套状态,这些状态的模板会在站点内各个非嵌套位置填充ui视图。在这种情况下,您不能期望在子状态的视图中访问父状态视图的范围变量。
因此,只要将我们的controller _( 带有模板,控制器的 视图 …)_注入父对象的目标中,ui-view="..."它就会继承继承的范围:
controller
ui-view="..."
newScope = scope.$new();
简而言之,这意味着 JS对象 _(例如scope.Model = {})_可以在子对象和父 对象 之间共享。
scope.Model = {}
$scope.Model.id = 1; // will refer to the same id in both parent & child
但是 ,基本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
3.当我切换状态并返回到状态时,会发生什么-另一个控制器是否被实例化?
这取决于。
如果将父子视图 (ui-view="title"上面记住)_替换为子视图,然后将其重新创建 (从_ 子视图 过渡到父 视图 ) -则将重新初始化此类控制器(如上所述)。
但是,当我们谈论 主要的父视图 (通常是未命名的)时 ,它代表 了父 视图(例如,下面带有控制器“ParentMainCtrl”的未命名视图)
.state('parent', { views : { '' : { // // the main parent view controller: 'ParentMainCtrl', } 'title@parent' 'tooltip@parent' },
然后,我们可以确定该控制器没有重新实例化。它生活在所有孩子的寿命中,加上父母的 孩子(未选择孩子的状态) 。
要重新加载此视图/控制器,我们必须使用一个选项 reload
reload
router/site/#/api/ui.router.state.$state)
… options选项对象。选项包括:
{boolean=false}
希望那些对你有帮助。有关更多信息,请查看以下资源: