UI-路由器 - 作用域在状态改变时没有被破坏?
UI-Router - scope not destroyed on state change?
我是 AngularJS 和 ui-router 的新用户,我正在努力了解范围的管理方式。我原以为活动控制器的范围会在状态更改时变为非活动状态时被破坏,但是,情况似乎并非如此。
我修改了 UI-Router 网站上的示例来说明情况(请参阅下面的 plunker)。每次触发状态 route1.list/route2.list 时,它们都会在 $rootScope 上发出一个事件。收到事件后,调试语句将打印到控制台。
通过多次在两种状态之间切换,可以观察到所有先前初始化的控制器都响应了该事件。所以看起来他们创建的范围从未被销毁过。这种行为是预期的吗?如果是这样,我应该怎么做才能让只有活动的控制器响应事件?
控制台上打印的调试消息:
代码:
var myapp = angular.module('myapp', ["ui.router"])
myapp.config(function($stateProvider, $urlRouterProvider){
// For any unmatched url, send to /route1
$urlRouterProvider.otherwise("/route1")
这是路线1
$stateProvider
.state('route1', {
url: "/route1",
templateUrl: "route1.html"
})
.state('route1.list', {
url: "/list",
templateUrl: "route1.list.html",
controller: function($rootScope, $scope){
$rootScope.$emit("eventCT1");
$rootScope.$on("eventCT2", fn);
function fn () {
console.log("Controller 1 receives an event emitted by Controller 2");
}
$scope.items = ["A", "List", "Of", "Items"];
}
})
这是路线 2
.state('route2', {
url: "/route2",
templateUrl: "route2.html"
})
.state('route2.list', {
url: "/list",
templateUrl: "route2.list.html",
controller: function($rootScope, $scope){
$rootScope.$emit("eventCT2");
$rootScope.$on("eventCT1", fn);
function fn () {
console.log("Controller 2 receives an event emitted by Controller 1");
}
$scope.things = ["A", "Set", "Of", "Things"];
}
})
...
如果我们想用
做点什么
1) $rootScope
控制器内部 (寿命非常有限),
2) 我们必须销毁它,当控制器 (实际上是 $scope
) 被销毁时
所以,这就是挂钩和解钩的方法
// get remove function
var removeMe = $rootScope.$on("eventCT2", ...);
// call that function
$scope.$on("$destroy", removeMe)
但是,在上述情况下,我们甚至不应该尝试
1) 为一个状态创建一些控制器动作...
2) 并期望它会在来自不同状态的另一个控制器中调用
他们永远不会住在一起[=13=]
如果您将 Ionic 与 Angular 一起使用,您可以像这样使用 life cycle events:
$scope.$on("$ionicView.beforeEnter", function(){
//Do something every time this controller is the active scope.
})
您也可以尝试上面 link 中提供的其他事件。最好的做法可能是尽量减少 $emit
的使用,这将导致更可预测的代码和更少的状态突变。
我是 AngularJS 和 ui-router 的新用户,我正在努力了解范围的管理方式。我原以为活动控制器的范围会在状态更改时变为非活动状态时被破坏,但是,情况似乎并非如此。
我修改了 UI-Router 网站上的示例来说明情况(请参阅下面的 plunker)。每次触发状态 route1.list/route2.list 时,它们都会在 $rootScope 上发出一个事件。收到事件后,调试语句将打印到控制台。
通过多次在两种状态之间切换,可以观察到所有先前初始化的控制器都响应了该事件。所以看起来他们创建的范围从未被销毁过。这种行为是预期的吗?如果是这样,我应该怎么做才能让只有活动的控制器响应事件?
控制台上打印的调试消息:
代码:
var myapp = angular.module('myapp', ["ui.router"])
myapp.config(function($stateProvider, $urlRouterProvider){
// For any unmatched url, send to /route1
$urlRouterProvider.otherwise("/route1")
这是路线1
$stateProvider
.state('route1', {
url: "/route1",
templateUrl: "route1.html"
})
.state('route1.list', {
url: "/list",
templateUrl: "route1.list.html",
controller: function($rootScope, $scope){
$rootScope.$emit("eventCT1");
$rootScope.$on("eventCT2", fn);
function fn () {
console.log("Controller 1 receives an event emitted by Controller 2");
}
$scope.items = ["A", "List", "Of", "Items"];
}
})
这是路线 2
.state('route2', {
url: "/route2",
templateUrl: "route2.html"
})
.state('route2.list', {
url: "/list",
templateUrl: "route2.list.html",
controller: function($rootScope, $scope){
$rootScope.$emit("eventCT2");
$rootScope.$on("eventCT1", fn);
function fn () {
console.log("Controller 2 receives an event emitted by Controller 1");
}
$scope.things = ["A", "Set", "Of", "Things"];
}
})
...
如果我们想用
做点什么1) $rootScope
控制器内部 (寿命非常有限),
2) 我们必须销毁它,当控制器 (实际上是 $scope
) 被销毁时
所以,这就是挂钩和解钩的方法
// get remove function
var removeMe = $rootScope.$on("eventCT2", ...);
// call that function
$scope.$on("$destroy", removeMe)
但是,在上述情况下,我们甚至不应该尝试
1) 为一个状态创建一些控制器动作...
2) 并期望它会在来自不同状态的另一个控制器中调用
他们永远不会住在一起[=13=]
如果您将 Ionic 与 Angular 一起使用,您可以像这样使用 life cycle events:
$scope.$on("$ionicView.beforeEnter", function(){
//Do something every time this controller is the active scope.
})
您也可以尝试上面 link 中提供的其他事件。最好的做法可能是尽量减少 $emit
的使用,这将导致更可预测的代码和更少的状态突变。