在ui-router中更改路径之前销毁范围

时间:2015-05-17 14:03:13

标签: javascript angularjs angularjs-scope angular-ui-router

我使用UI-Router路由。当我将路径从状态更改为另一个状态并返回到相同状态时,我看到状态中的旧$ scope是(带有它的属性)

我想在状态改变之前消灭那个$ scope,所以当我第二次回到状态时,会有一个干净的新范围。我试图在这个事件中访问范围:

$rootScope.$on('$stateChangeStart', 
   function(event, toState, toParams, fromState, fromParams) {
     // fromState.$scope.$destroy();
});

但是没有任何对范围的引用。我可以在角度UI-Router更改状态之前访问范围吗?

2 个答案:

答案 0 :(得分:5)

我会说,你所经历的与你描述的有点不同,或者你认为发生了什么。请检查例如:

一般情况下,状态更改完成后(未拒绝), $范围肯定是已销毁。如果我们导航然后返回,则会为我们创建新的$scope。但是这个 $ scope 是这样创建的:

viewDirective.js

的源代码
    function updateView(firstTime) {
      var newScope,
          name            = getUiViewName(scope, attrs, $element, $interpolate),
          previousLocals  = name && $state.$current && $state.$current.locals[name];

      if (!firstTime && previousLocals === latestLocals) return; // nothing to do
      // HERE
      newScope = scope.$new();
      ...

构造: scope.$new(); 是理解的关键。这实际上意味着我们使用原型继承

简而言之,可以描述:

  

我们提供了一个$scope,它已从其父级克隆了所有属性。

所以如果父包含一些引用(在路径中有'。'),就像这样

// parent scope
$scope.Model = {
  ...
};

任何儿童状态都会像这样改变

$scope.Model.name = "User";

该值将存储在状态 $ scope 中,并且可用于此状态的任何下一个

注意:如果我们离开州,可以使用相同的viewDirective.js but elswhere来证明这一事实 - $scope is destroyed

    function cleanupLastView() {
      if (previousEl) {
        previousEl.remove();
        previousEl = null;
      }

      if (currentScope) {
        currentScope.$destroy();
        currentScope = null;
      }
      ...

EXTEND

我使用以下两种状态创建了a working example here

.controller('ParentCtrl', ['$scope', function ($scope) { 
  $scope.Model = {
    SharedName: "This is shared name",
  }
  $scope.NotSharedName = $scope.NotSharedName 
                      || "This name is cloned, but then lives its own way";
}])
.controller('ChildCtrl', ['$scope', function ($scope) {}])

以下两种方式如何更改值(所有都将遵循上述逻辑)

<p>this will be shared among all children and parent
  <input ng-model="Model.SharedName" />
</p>
<p>this will always copied from parent, live then in each child
  <input ng-model="NotSharedName" />
</p>

检查here

答案 1 :(得分:3)

我打算对RadimKöhler的帖子做一个附加评论,但由于我没有足够的重复点,我只是在这里添加一个答案,到目前为止我用来避免这个问题的唯一解决方案是使用"controller as"方法并避免在控制器范围上添加方法/属性,我不希望由于原型行为而导致冲突。