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.

中使用可读查询参数是值得的