Angular UI Router Reload Controller on Back Button Press

时间:2015-05-05 21:25:41

标签: angularjs angular-ui angular-routing

我的路线可以有许多可选的查询参数:

$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},指示我的服务是否会被查询。

除非用户点击浏览器的前进和/或后退按钮,否则此功能非常有效。在这两种情况下,状态(路由)都会正确更改查询参数,但不会重新加载controller

根据我的阅读,只有在实际路线发生变化时才会重新加载控制器。反正是为了让这个例子只使用查询参数工作还是我必须使用不断变化的路径?

2 个答案:

答案 0 :(得分:6)

您应该收听事件以获得成功的页面更改,$ 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();
});  

答案 1 :(得分:1)

使用上述内容,我能够找到解决问题的方法:

controller(代码段):

...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中使用可读的查询参数。