在 ui-router 中更改路径之前销毁作用域
Destroy scope before change path in ui-router
我使用UI-Router
路由。当我将路径从一个状态更改为另一个状态并返回到相同状态时,我看到状态中的旧 $scope 在那里 (及其属性).
我想在状态改变之前销毁那个$scope,所以当我第二次回到状态时,会有一个干净的新范围。我试图在此事件中访问范围:
$rootScope.$on('$stateChangeStart',
function(event, toState, toParams, fromState, fromParams) {
// fromState.$scope.$destroy();
});
但是没有任何对 $scope 的引用。我可以在 angular UI-Router
中更改状态之前访问范围吗?
我会说,您所经历的与您描述的有点不同,或者您认为正在发生的事情。请检查例如:
- How do I share $scope data between states in angularjs ui-router?
一般来说,一旦状态更改完成(不是拒绝),old $scope 肯定会 destroyed。如果我们导航然后返回,则会为我们创建新的 $scope
。但是这个 $scope 是这样创建的:
的源代码
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();
是理解的关键。这实际上意味着,我们使用原型继承
- What are the nuances of scope prototypal / prototypical inheritance in AngularJS?
简而言之可以描述为:
we are provided with a $scope
which has cloned all the properties from its parent.
因此,如果父项包含一些引用(路径中有“.”),就像这样
// parent scope
$scope.Model = {
...
};
任何子状态都会像这样改变
$scope.Model.name = "User";
该值将存储在 parent state $scope 中并再次可用...对于任何下一个 child 这个州。
注意:相同的 viewDirective.js but elswhere 可用于证明事实 - $scope is destroyed
如果我们离开状态:
function cleanupLastView() {
if (previousEl) {
previousEl.remove();
previousEl = null;
}
if (currentScope) {
currentScope.$destroy();
currentScope = null;
}
...
延长
我创建了 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
我本来打算对 Radim Köhler 的 post 做一个附加评论,但由于我没有足够的代表点数,我将在这里添加一个答案,这是我使用过的唯一解决方案到目前为止,要避免这种情况是使用 "controller as" 方法并避免在控制器范围内添加 methods/properties ,我不希望由于原型行为而发生冲突。
我使用UI-Router
路由。当我将路径从一个状态更改为另一个状态并返回到相同状态时,我看到状态中的旧 $scope 在那里 (及其属性).
我想在状态改变之前销毁那个$scope,所以当我第二次回到状态时,会有一个干净的新范围。我试图在此事件中访问范围:
$rootScope.$on('$stateChangeStart',
function(event, toState, toParams, fromState, fromParams) {
// fromState.$scope.$destroy();
});
但是没有任何对 $scope 的引用。我可以在 angular UI-Router
中更改状态之前访问范围吗?
我会说,您所经历的与您描述的有点不同,或者您认为正在发生的事情。请检查例如:
- How do I share $scope data between states in angularjs ui-router?
一般来说,一旦状态更改完成(不是拒绝),old $scope 肯定会 destroyed。如果我们导航然后返回,则会为我们创建新的 $scope
。但是这个 $scope 是这样创建的:
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();
是理解的关键。这实际上意味着,我们使用原型继承
- What are the nuances of scope prototypal / prototypical inheritance in AngularJS?
简而言之可以描述为:
we are provided with a
$scope
which has cloned all the properties from its parent.
因此,如果父项包含一些引用(路径中有“.”),就像这样
// parent scope
$scope.Model = {
...
};
任何子状态都会像这样改变
$scope.Model.name = "User";
该值将存储在 parent state $scope 中并再次可用...对于任何下一个 child 这个州。
注意:相同的 viewDirective.js but elswhere 可用于证明事实 - $scope is destroyed
如果我们离开状态:
function cleanupLastView() {
if (previousEl) {
previousEl.remove();
previousEl = null;
}
if (currentScope) {
currentScope.$destroy();
currentScope = null;
}
...
延长
我创建了 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
我本来打算对 Radim Köhler 的 post 做一个附加评论,但由于我没有足够的代表点数,我将在这里添加一个答案,这是我使用过的唯一解决方案到目前为止,要避免这种情况是使用 "controller as" 方法并避免在控制器范围内添加 methods/properties ,我不希望由于原型行为而发生冲突。