Skip to main content
 首页 » 编程设计

angularjs之使用 ui 路由器的范围和 Controller 实例化

2024年07月26日26exmyth

我对 Controller 何时被实例化感到困惑。此外,在嵌套状态时如何实例化 Controller 。我可能对范围如何附加到 View 和 Controller 感到困惑,也就是说,如果每个 View 都有自己的 Controller 和范围,或者它们是否共享相同的范围。

有人可以解释一下 Controller 何时被实例化吗?在嵌套路由下,所有 View 是否共享一个 Controller 和作用域?当我切换状态并返回另一个 Controller 被实例化的状态时会发生什么?

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

.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. When do controllers get instantiated?



这里我们可以观察到 ui-view的代码指示:
[$ViewDirective.$inject = \['$state', '$injector', '$uiViewScroll', '$interpolate'\];][1]
Controller 相关于 浏览次数 .那些 views , 定义在 .state() 内如 views 目的:
.state('...', { 
  // The view definition 
  views : { 
    '' : { 
      template: ... 
      controller: ... 
      resolve: .. 
    } 
  }, 
  resolve: ... 
} 

因此,每当 View ( ui-view )充满状态 View 内部定义的设置时,它几乎充当 标准但增强的指令 .

1)找到模板,
2) 解析已解析
...
x) Controller 被实例化...

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

这可能意味着,一个 View 中可能有内容(例如 title ),由 定义家长 以及替换为 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" 
  }, 
  ... 
} 

上面的状态定义(每当我们在这两个状态之间转换时)会:
  • $state.go('parent') - 在 'title@parent' : { ...} 中定义的 View (模板、 Controller ...)将注入(inject)目标 ui-view="title"并如上所述实例化
  • $state.go('parent.child') - 几乎相同,只是 View 将从子状态/ View 定义中获取 'title' : { ...} .这将替换 ui-view="title" 的内容并将按上述方式实例化

  • 每次我们从 parent 到 child ,从 child 到 parent 时,都会发生这种情况。

    2. Under nested routes do all the views share one controller and scope?



    一个简单的答案是 ,还有 共同分享。

    事实上, 每个 Controller 自己的范围 ,从父 View 范围创建的。首先是文档:

    What Do Child States Inherit From Parent States?

    ...

    Scope Inheritance by View Hierarchy Only

    Keep in mind that scope properties only inherit down the state chain if the views of your states are nested. Inheritance of scope properties has nothing to do with the nesting of your states and everything to do with the nesting of your views (templates).

    It is entirely possible that you have nested states whose templates populate ui-views at various non-nested locations within your site. In this scenario you cannot expect to access the scope variables of parent state views within the views of children states.



    所以,无论何时我们的 controller (以及 View 带有模板、 Controller ...)注入(inject)父对象的目标 ui-view="..."它获得继承范围:
    newScope = scope.$new(); 
    

    简而言之,这意味着 JS 对象 (例如 scope.Model = {} )可以在 child 和 parent 之间共享。
    $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 
    

    值得在这里阅读更多关于原型(prototype)继承的信息:
    What are the nuances of scope prototypal / prototypical inheritance in AngularJS?

    3. What happens when I switch states and go back to a state - does another controller get instantiated?



    这取决于。

    如果父 subview (请记住上面的 ui-view="title")被 subview 替换,然后重新创建(从 subview 过渡到父 View ) - 这样的 Controller 将被重新初始化(上面讨论过)。

    但是当我们谈到 主父 View (通常未命名),代表 (例如下面带有 Controller “ParentMainCtrl”的未命名 View )
    .state('parent', { 
      views : { 
        '' : {  //  // the main parent view 
          controller: 'ParentMainCtrl', 
        } 
        'title@parent' 
        'tooltip@parent' 
      }, 
    

    然后我们可以确定这样的 Controller 不会被重新实例化。它生活在它所有 child 的一生中,加上 parent 的一个(没有选择 child 状态)。

    要重新加载这个 View / Controller ,我们必须使用一个选项 reload
    $state.go(to, params, options)

    ... options Options object. The options are:


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

  • 希望那些对你有帮助。有关更多信息,请查看以下资源:
  • Nested States & Nested Views
  • Multiple Named Views
  • API Reference
  • State.jsthe sample application - 我会说最好的代码片段 曾经