AngularJS页面刷新后跨控制器传递的服务值丢失问题求助
解决AngularJS页面刷新后服务数据丢失的问题
问题的核心在于:AngularJS的服务是内存中的单例对象,当页面刷新时,整个Angular应用会重新初始化,服务里存储的临时数据会被完全清空,所以另一个控制器自然拿不到之前存入的值。下面给你几个实用的解决办法:
方法1:使用本地存储(localStorage/sessionStorage)持久化数据
这是最常用的方案,把数据存在浏览器的本地存储里,刷新后依然能读取到。修改你的setProperties服务,在存值和取值时加上本地存储的操作:
angular.module('myApp', []) .service('setProperties', function () { // 存ID的方法 this.setId = function(Id) { // 同时存在内存和localStorage this.id = Id; localStorage.setItem('selectedItemId', Id); }; // 获取ID的方法 this.getId = function() { // 优先从内存取,没有的话从localStorage读取 return this.id || localStorage.getItem('selectedItemId'); }; });
这样即使页面刷新,调用getId()时会从localStorage里读取之前保存的ID,就不会丢失数据了。如果不需要长期保存,也可以用sessionStorage,它会在浏览器关闭后清空。
方法2:通过路由参数传递ID
既然你用了ui-sref跳转,可以直接把ID作为路由参数传递,这样刷新页面后目标控制器依然能通过路由参数拿到ID。
首先修改你的HTML链接:
<div id="{{item.codeName}}"> <a class="search-results" ui-sref="app.location({id: item._id})" ng-click="vm.setValue(item._id)"> {{item.codeName}} </a><br><br> </div>
然后配置你的app.location路由(假设用的是ui-router):
angular.module('myApp') .config(function($stateProvider) { $stateProvider.state('app.location', { url: '/location/:id', // 加上id参数 templateUrl: 'location.html', controller: 'Controller2' }); });
最后在目标控制器(Controller2)里用$stateParams获取ID:
angular.module('myApp') .controller('Controller2', function($stateParams, setProperties) { // 直接从路由参数拿ID,也可以存入服务 var itemId = $stateParams.id; setProperties.setId(itemId); });
这种方法的好处是URL里会带上ID,用户刷新页面或者分享链接都能正常获取到数据。
方法3:路由resolve预加载数据(如果需要从后端获取)
如果你的ID对应着后端的一条数据,还可以在路由里配置resolve,提前从后端获取数据,这样页面刷新时会自动重新请求数据:
angular.module('myApp') .config(function($stateProvider) { $stateProvider.state('app.location', { url: '/location/:id', templateUrl: 'location.html', controller: 'Controller2', resolve: { itemData: function($stateParams, $http) { // 根据ID从后端获取数据 return $http.get('/api/items/' + $stateParams.id) .then(function(response) { return response.data; }); } } }); });
然后在Controller2里直接注入itemData使用:
angular.module('myApp') .controller('Controller2', function(itemData, setProperties) { // 拿到数据后可以存入服务 setProperties.setId(itemData._id); });
这样即使刷新页面,路由会先请求数据,确保控制器拿到最新的内容。
内容的提问来源于stack exchange,提问作者HKI345
相关产品推荐
相关产品推荐

