使用ui路由器进行范围和控制器实例化

eNd*_*ddy 25 angularjs angularjs-scope angularjs-routing angular-ui-router

我很困惑控制器何时实例化.此外,嵌套状态时控制器如何实例化.我可能会对范围如何附加到视图和控制器感到困惑,也就是说,如果每个视图都有自己的控制器和范围,或者它们共享相同的范围.

有人可以解释控制器何时实例化?在嵌套路由下,所有视图共享一个控制器和范围吗?当我切换状态并返回状态会发生另一个控制器实例化时会发生什么?

以下是我的路线(配置文件):

.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'
      }
    }
  })
Run Code Online (Sandbox Code Playgroud)

Rad*_*ler 33

为了获得更详细的答案,我们可以/应该观察源代码并检查文档.让我试着解释所有三个问题(也可以从代码和文档中引用).

1.控制器什么时候实例化?

在这里我们可以观察ui-view指令的代码:

[$ViewDirective.$inject = \['$state', '$injector', '$uiViewScroll', '$interpolate'\];][1]

控制器与视图相关.那些views在a .state()作为views对象内部定义的:

.state('...', {
  // The view definition
  views : {
    '' : {
      template: ...
      controller: ...
      resolve: ..
    }
  },
  resolve: ...
}
Run Code Online (Sandbox Code Playgroud)

因此,只要view(the ui-view)填充了状态视图中定义的设置,它几乎就像标准但增强的指令一样.

1)找到模板,
2)解析解析
...
x)控制器实例化...

视图目标(ui-view指令)可以使用名称,并且可以由层次结构中的不同状态填充.

这可能意味着,一个视图(例如标题)内部可能存在内容,由父级定义以及由子级替换

// 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"
  },
  ...
}
Run Code Online (Sandbox Code Playgroud)

上述状态定义将(每当我们在这两个状态之间转换时)执行:

  • $state.go('parent')-在定义的视图(模板,控制器...)'title@parent' : { ...}将被注入到目标ui-view="title"并如上所述实例化

  • $state.go('parent.child')-几乎是相同的,只是视图将从子状态/图确定指标采取'title' : { ...}.这将取代其内容,ui-view="title"并将如上所述进行实例化

每次我们从父母到孩子,从孩子到父母,都会发生这种情况.

2.在嵌套路由下,所有视图共享一个控制器和范围吗?

一个简单的答案是否定的,没有共同的共享.

实际上,每个控制器都有自己的作用域,即从父视图作用域创建的作用域.首先是文档:

儿童国家对父母国家的继承是什么?

...

仅按视图层次结构的范围继承

请记住,只有嵌套状态的视图时,范围属性才会继承状态链.范围属性的继承与状态的嵌套以及与视图(模板)的嵌套有关的所有内容都无关.

完全有可能您有嵌套状态,其模板在您站点内的各种非嵌套位置填充ui-views.在这种情况下,您不能指望在子状态视图中访问父状态视图的范围变量.

因此,无论何时我们controller (以及模板,控制器...... 的视图)注入到父目标中,ui-view="..."它都会获得继承范围:

newScope = scope.$new();
Run Code Online (Sandbox Code Playgroud)

简而言之,这意味着JS对象 (例如scope.Model = {})可以在子级和父级之间共享.

$scope.Model.id = 1; // will refer to the same id in both parent & child
Run Code Online (Sandbox Code Playgroud)

但是,基本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
Run Code Online (Sandbox Code Playgroud)

值得一提的是关于原型继承的更多内容:
AngularJS中范围原型/原型继承的细微差别是什么?

3.当我切换状态并返回状态时会发生什么 - 另一个控制器是否被实例化?

这取决于.

如果父子视图(ui-view="title"上面记得)被子视图替换,然后它被重新创建(从子级转换到父级) - 这样的控制器将被重新初始化(如上所述).

但是当我们谈到主父视图 (通常是未命名的)时,它代表了父 视图(例如下面带有控制器'ParentMainCtrl'的未命名视图)

.state('parent', {
  views : {
    '' : {  //  // the main parent view
      controller: 'ParentMainCtrl',
    }
    'title@parent'
    'tooltip@parent'
  },
Run Code Online (Sandbox Code Playgroud)

然后我们可以确定不会重新实例化这样的控制器.它生活在其所有孩子的一生中,加上父母的孩子(没有选择儿童州).

要重新加载此视图/控制器,我们必须使用一个选项 reload

$ state.go(to,params,options)

...选项选项对象.选项是:

  • ...
  • reload - {boolean=false},如果true将强制转换,即使状态或参数没有改变,也就是重新加载相同的状态.它与reloadOnSearch不同,因为当你想在一切都相同时强制重新加载时你会使用它,包括搜索参数.

希望有点帮助.有关详细信息,请查看以下资源: