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
?
source to share
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:
- How to share $ scope data between states in angularjs url router?
- scoping and implementing controller with ui router
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
source to share
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.
source to share