Destroy the scope before the change path in u-router

I am using routing UI-Router

. When I change the path from state to another and return to the same state, I see that the old $ scope exists in the state (with its properties).

I want to destroy this $ area before state changes. So when I go back to the state a second time, a new new area will appear. In this case, I tried to access the scope:

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

      

But there is no link to $ scope. Can I access the scope before the change state in angular UI-Router

?

+3


source to share


2 answers


I would say that what you are experiencing is slightly different from what you described or what you thought is happening. Please check for example the following:

Typically, after a state change (not rejected), the old $ area is definitely destroyed . If we then move back, a new one will be created for us $scope

. But this $ scope is created like this:

ViewDirective.js Source Code

    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();
      ...

      

Construction: is the key to understanding. This actually means that we are using prototypical inheritance scope.$new();

And this can be described in a nutshell:

we are provided $scope

which has cloned all properties from its parent.

So if parent element contains some link (has "." In path) like this

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

      



And any child state will change as if

$scope.Model.name = "User";

      

This value will be stored in the parent $ scope state and will be available again ... for any next child of that state.

NOTE: to demonstrate the fact, you can use the same viewDirective.js, but elswhere - if you leave the state: $scope is destroyed

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

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

      

EXTEND

I created a working example here with these two states:

.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) {}])

      

And these two ways how to change the values ​​(all will follow the logic described above):

<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>

      

Check here

+4


source


I was going to make an additional comment on Radim Köhler's post, but since I don't have enough points I'll just add an answer here that the only solution I've used so far to get around this is to use "controller as" and avoid adding methods / properties in the controller scope that I don't want to contradict due to prototypal behavior.



+2


source







All Articles