如何在浏览器刷新时保留ui-router参数

时间:2021-09-13 11:55:43

am using angular ui-router to manage states of my SPA. I have this route:

我使用角度ui-router来管理我的SPA的状态。我有这条路线:

    .state('index.administration.security.roleEdit', {
                url: '/roleEdit',
                templateUrl: 'app/administration/security/role/roleEdit.html',
                controller: 'roleEditCtrl',
                controllerAs: 'roleEditCtrl',
                params: { data: null },
                resolve: {
                    role: function ($stateParams) {
                        return angular.fromJson($stateParams.data);
                    },
                    modules: function (securityService) {
                        return securityService.getAllModules();
                    }                       
                }
            })

Also, I'm passing 'data' parameter as json object to the state. Now when i first load this state, everything is fine. But when i do browser refresh (F5 key) the $stateParams.data is null in the resolve function of the state.

另外,我将'data'参数作为json对象传递给状态。现在当我第一次加载这个状态时,一切都很好。但是当我进行浏览器刷新(F5键)时,$ stateParams.data在状态的resolve函数中为null。

How can I solve this? I see these possible solutions: 1. persist somehow parameters 2. override browser refresh (don't know how) to stop the browser refreshing the app. 3. on refresh goto other sibling state.

我怎么解决这个问题?我看到了这些可能的解决方案:1。以某种方式坚持参数2.覆盖浏览器刷新(不知道如何)停止浏览器刷新应用程序。 3.刷新goto其他兄弟状态。

Please help

UPDATE Ok, I set data like this:

更新好的,我设置这样的数据:

vm.editRole = function(roleId){
     var role = dataService.getRoleById(roleId).then(function(result){
           $state.go('roleEdit', {data:angular.toJson(result)});
           });
}

UPDATE 2 The roleEdit Controller looks like this:

更新2 roleEdit控制器如下所示:

(function(){
    angular.module('app.administration').controller('roleEdit', 
    ['role','modules', '$scope', 'securityService', '$state', roleEditCtrl]);

    function roleEditCtrl('role', 'modules',$scope, securityService, $state){
        var vm = this;
        vm.roles = roles;
        vm.originalRole = angular.copy(role);
        vm.modules=modules;
        vm.saveChanges = _saveChanges;
        vm.cancel = _cancel;

        return vm;

        function _saveChanges(){
            securityService.UpdateRole(vm.role).then(function(result){
                $staste.go('^.roles');
            }
        }

        function _cancel(){
            vm.role = angular.copy(vm.originalRole);
            $sscope.roleEditForm.$setPristine();            
        }
    }
})();

2 个解决方案

#1


1  

Had the same problem, leaving this here in case someone else needs it. Solved it by using localStorage.

有同样的问题,留下这个以防其他人需要它。通过使用localStorage解决了它。

I've set this as a part of app's run method

我把它设置为app的run方法的一部分

$rootScope.$on('$stateChangeSuccess', function (event, toState) {
    localStorage.setItem('__stateName', toState.name);
});

Now, depending on your app's structure you might want to consider putting this someplace else, but in my case I had parent AppController surrounding all child controllers, so this part of the code went there.

现在,根据您的应用程序的结构,您可能需要考虑将其放在其他位置,但在我的情况下,我有所有子控制器的父AppController,所以这部分代码就在那里。

var previousState = localStorage.getItem('__stateName');
previousState && $state.go(previousState) || $state.go(<SOME_OTHER_ROUTE>);

Basically, when user hits browser refresh, AppController get initialized from the start (before child controllers), firing the state transition immediately if there was one. Otherwise, you'd go to some other state of yours.

基本上,当用户点击浏览器刷新时,AppController从开始(在子控制器之前)初始化,如果有的话,立即触发状态转换。否则,你会去其他一些州。

#2


0  

I would stay away from option 2. You don't want to mess up a browser's expected behavior.

我会远离选项2.你不想搞砸浏览器的预期行为。

Maybe you could refactor your data into your resolve object ala:

也许你可以将你的数据重构到你的解析对象ala:

resolve: {
           role: function ($stateParams) {
               return angular.fromJson($stateParams.data);
           },
           modules: function (securityService) {
               return securityService.getAllModules();
           },
           data: function (dataService) {
               return dataService.retrieveStoredData();
           }

Where your dataService would be a service you use to store that data if it really is that important (through cookies or localstorage).

如果dataService确实非常重要(通过cookie或localstorage),那么您的dataService将用于存储该数据。

There is no reasonable way to expect that field to be populated on browser refresh if you previously executed javascript to pass stateful values to it.

如果您之前执行了javascript以向其传递有状态值,则没有合理的方法可以在浏览器刷新时填充该字段。

#1


1  

Had the same problem, leaving this here in case someone else needs it. Solved it by using localStorage.

有同样的问题,留下这个以防其他人需要它。通过使用localStorage解决了它。

I've set this as a part of app's run method

我把它设置为app的run方法的一部分

$rootScope.$on('$stateChangeSuccess', function (event, toState) {
    localStorage.setItem('__stateName', toState.name);
});

Now, depending on your app's structure you might want to consider putting this someplace else, but in my case I had parent AppController surrounding all child controllers, so this part of the code went there.

现在,根据您的应用程序的结构,您可能需要考虑将其放在其他位置,但在我的情况下,我有所有子控制器的父AppController,所以这部分代码就在那里。

var previousState = localStorage.getItem('__stateName');
previousState && $state.go(previousState) || $state.go(<SOME_OTHER_ROUTE>);

Basically, when user hits browser refresh, AppController get initialized from the start (before child controllers), firing the state transition immediately if there was one. Otherwise, you'd go to some other state of yours.

基本上,当用户点击浏览器刷新时,AppController从开始(在子控制器之前)初始化,如果有的话,立即触发状态转换。否则,你会去其他一些州。

#2


0  

I would stay away from option 2. You don't want to mess up a browser's expected behavior.

我会远离选项2.你不想搞砸浏览器的预期行为。

Maybe you could refactor your data into your resolve object ala:

也许你可以将你的数据重构到你的解析对象ala:

resolve: {
           role: function ($stateParams) {
               return angular.fromJson($stateParams.data);
           },
           modules: function (securityService) {
               return securityService.getAllModules();
           },
           data: function (dataService) {
               return dataService.retrieveStoredData();
           }

Where your dataService would be a service you use to store that data if it really is that important (through cookies or localstorage).

如果dataService确实非常重要(通过cookie或localstorage),那么您的dataService将用于存储该数据。

There is no reasonable way to expect that field to be populated on browser refresh if you previously executed javascript to pass stateful values to it.

如果您之前执行了javascript以向其传递有状态值,则没有合理的方法可以在浏览器刷新时填充该字段。