ui router - 具有共享控制器的嵌套视图

aw0*_*w04 32 angularjs angular-ui-router

我有一个抽象的父视图,旨在与其嵌套视图共享一个控制器.

.state('edit', {
    abstract: true,
    url: '/home/edit/:id',
    templateUrl: 'app/templates/editView.html',
    controller: 'editController'
})
.state('edit.details', {
    url: '/details',
    templateUrl: 'app/templates/editDetailsView.html'
})
.state('edit.info', {
    url: '/info',
    templateUrl: 'app/templates/editInfoView.html'
})
Run Code Online (Sandbox Code Playgroud)

路由按预期工作.

问题是当我$scope从其中一个嵌套视图更新变量时,更改不会反映在视图中.当我从父视图中执行相同操作时,它可以正常工作.这不是需要的情况$apply.

我的猜测是editController为每个视图创建了一个新实例,但我不确定为什么或如何修复它.

Rad*_*ler 41

这里的问题与此问答有关:如何在angularjs ui-router中的状态之间共享$ scope数据?.

如何解决它的方式隐藏在:

了解范围

在AngularJS中,子范围通常原型继承自其父范围.
...

有一个 '.' 在你的模型中将确保原型继承发挥作用.

// So, use
<input type="text" ng-model="someObj.prop1"> 
// rather than
<input type="text" ng-model="prop1">.
Run Code Online (Sandbox Code Playgroud)

还有这个

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

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

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

我们应该在编辑Controller中执行此操作

controller('editController', function ($scope) {
  $scope.Model = $scope.Model || {SomeProperty : "xxx"};
})
Run Code Online (Sandbox Code Playgroud)

我们甚至可以重用它controller: 'editController' (我们不必这样做,因为$ scope.Model将存在 - 感谢继承)

.state('edit', {
    abstract: true,
    url: '/home/edit/:id',
    templateUrl: 'app/templates/editView.html',
    controller: 'editController'
})
.state('edit.details', {
    url: '/details',
    templateUrl: 'app/templates/editDetailsView.html',
    controller: 'editController'
})
.state('edit.info', {
    url: '/info',
    templateUrl: 'app/templates/editInfoView.html',
    controller: 'editController'
})
Run Code Online (Sandbox Code Playgroud)

现在,同一个控制器将被多次实例化(父所有子节点),但$scope.Model只会启动一次(在父节点内),并且可以在任何地方使用

在这里查看类似的工作示例


Rad*_*ler 14

根据PilotBob的评论

当使用controllerAs模式给孩子状态它自己的控制器时,是否可以这样做?

我决定controllerAs在保持上述/原始概念的同时附加另一种解决方案

一个工作的plunker

状态现在将具有不同的控制器,父状态将其命名为"parentCtrl" (在具有子控制器的子范围中不被覆盖)

 .state("main", {
      controller:'mainController',
      controllerAs: "parentCtrl",
      ...
  .state("main.1", {
      parent: 'main',
      controller:'child1Controller',
      controllerAs: "ctrl",
      ...
  .state("main.2", {
      parent: 'main',
      controller:'child2Controller',
      controllerAs: "ctrl", 
      ... 
Run Code Online (Sandbox Code Playgroud)

这些是控制器:

.controller('mainController', function ($scope) {
    this.Model =  {Name : "yyy"};
})
.controller('child1Controller', function ($scope) {
    $scope.Model = $scope.parentCtrl.Model;
})
.controller('child2Controller', function ($scope) {
    $scope.Model = $scope.parentCtrl.Model; 
})
Run Code Online (Sandbox Code Playgroud)

这里检查它