Angular UI 按下后退按钮时路由器重新加载控制器
Angular UI Router Reload Controller on Back Button Press
我有一个可以有很多可选查询参数的路由:
$stateProvider.state("directory.search", {
url: '/directory/search?name&email',
templateUrl: 'view.html',
controller: 'controller'
当用户填写表格以搜索目录时,$scope
中的一个函数会更改导致控制器重新加载的状态:
$scope.searchDirectory = function () {
$state.go('directory.search', {
name: $scope.Model.Query.name,
email: $scope.Model.Query.email
}, { reload: true });
};
在 controller
我有一个条件:if($state.params){return data}
指示是否查询我的服务。
除非用户单击浏览器的前进 and/or 后退按钮,否则效果很好。在这两种情况下,状态(路由)都会正确更改查询参数,但不会重新加载 controller
.
据我了解,只有当实际路线发生变化时,控制器才会重新加载。有没有办法让这个例子只使用查询参数工作,或者我必须使用变化的路由?
您应该监听页面更改成功的事件 $locationChangeSuccess。查看它的文档 https://docs.angularjs.org/api/ng/service/$location.
这里也回答了类似的问题 How to detect browser back button click event using angular?。
当该事件触发时,您可以将 运行 控制器初始化时需要 运行 的任何逻辑放在页面加载上。
类似于:
$rootScope.$on('$locationChangeSuccess', function() {
$scope.searchDirectory()
});
或更好的设置,如:
var searchDirectory = function () {
$state.go('directory.search', {
name: $scope.Model.Query.name,
email: $scope.Model.Query.email
}, { reload: true });
$scope.searchDirectory = searchDirectory;
$rootScope.$on('$locationChangeSuccess', function() {
searchDirectory();
});
使用以上方法,我找到了解决问题的方法:
控制器(代码片段):
...var searchDirectory = function (searchParams) {
if (searchParams) {
$scope.Model.Query.name = searchParams.name;
$scope.Model.Query.email = searchParams.email;
}
$state.go('directory.search', {
name: $scope.Model.Query.name,
email: $scope.Model.Query.email,
}, { reload: true });
};...
$rootScope.$on('$locationChangeSuccess', function () {
//used $location.absUrl() to keep track of query string
//could have used $location.path() if just interested in the portion of the route before query string params
$rootScope.actualLocation = $location.absUrl();
});
$rootScope.$watch(function () { return $location.absUrl(); }, function (newLocation, oldLocation) {
//event fires too often?
//before complex conditional was used the state was being changed too many times causing a saturation of my service
if ($rootScope.actualLocation && $rootScope.actualLocation !== oldLocation && oldLocation !== newLocation) {
searchDirectory($location.search());
}
});
$scope.searchDirectory = searchDirectory;
if ($state.params && Object.keys($state.params).length !== 0)
{..call to service getting data...}
此解决方案感觉更像是传统框架,例如 .net Web 表单,其中开发人员必须根据页面状态执行某些操作。我认为在 URL.
中使用可读查询参数是值得的
我有一个可以有很多可选查询参数的路由:
$stateProvider.state("directory.search", {
url: '/directory/search?name&email',
templateUrl: 'view.html',
controller: 'controller'
当用户填写表格以搜索目录时,$scope
中的一个函数会更改导致控制器重新加载的状态:
$scope.searchDirectory = function () {
$state.go('directory.search', {
name: $scope.Model.Query.name,
email: $scope.Model.Query.email
}, { reload: true });
};
在 controller
我有一个条件:if($state.params){return data}
指示是否查询我的服务。
除非用户单击浏览器的前进 and/or 后退按钮,否则效果很好。在这两种情况下,状态(路由)都会正确更改查询参数,但不会重新加载 controller
.
据我了解,只有当实际路线发生变化时,控制器才会重新加载。有没有办法让这个例子只使用查询参数工作,或者我必须使用变化的路由?
您应该监听页面更改成功的事件 $locationChangeSuccess。查看它的文档 https://docs.angularjs.org/api/ng/service/$location.
这里也回答了类似的问题 How to detect browser back button click event using angular?。
当该事件触发时,您可以将 运行 控制器初始化时需要 运行 的任何逻辑放在页面加载上。
类似于:
$rootScope.$on('$locationChangeSuccess', function() {
$scope.searchDirectory()
});
或更好的设置,如:
var searchDirectory = function () {
$state.go('directory.search', {
name: $scope.Model.Query.name,
email: $scope.Model.Query.email
}, { reload: true });
$scope.searchDirectory = searchDirectory;
$rootScope.$on('$locationChangeSuccess', function() {
searchDirectory();
});
使用以上方法,我找到了解决问题的方法:
控制器(代码片段):
...var searchDirectory = function (searchParams) {
if (searchParams) {
$scope.Model.Query.name = searchParams.name;
$scope.Model.Query.email = searchParams.email;
}
$state.go('directory.search', {
name: $scope.Model.Query.name,
email: $scope.Model.Query.email,
}, { reload: true });
};...
$rootScope.$on('$locationChangeSuccess', function () {
//used $location.absUrl() to keep track of query string
//could have used $location.path() if just interested in the portion of the route before query string params
$rootScope.actualLocation = $location.absUrl();
});
$rootScope.$watch(function () { return $location.absUrl(); }, function (newLocation, oldLocation) {
//event fires too often?
//before complex conditional was used the state was being changed too many times causing a saturation of my service
if ($rootScope.actualLocation && $rootScope.actualLocation !== oldLocation && oldLocation !== newLocation) {
searchDirectory($location.search());
}
});
$scope.searchDirectory = searchDirectory;
if ($state.params && Object.keys($state.params).length !== 0)
{..call to service getting data...}
此解决方案感觉更像是传统框架,例如 .net Web 表单,其中开发人员必须根据页面状态执行某些操作。我认为在 URL.
中使用可读查询参数是值得的