Angular 1.6.9切换用户登录后,如何更新Resource参数?
这个问题我之前在Angular 1.x项目里也碰到过,本质是**$resource初始化时的参数是一次性静态绑定**,而不是动态获取的。你当前的代码里,roleId和ulId是在BookResource工厂初始化时直接取了当时$localStorage.currentUser的值,之后即使$localStorage更新了,这些参数也不会自动同步。
方案一:用动态函数获取参数(最优解)
Angular 1.x的$resource支持把参数值定义为函数,每次发起请求时都会执行这个函数来获取最新值。只需要修改你的Resource定义:
angular.module('app').factory('BookResource', function($resource, $localStorage) { return $resource('/rest/:roleId/ul/:ulId/book/:id', { // 改成函数,每次请求都会重新获取最新的localStorage值 roleId: function() { return $localStorage.currentUser?.roleId; }, ulId : function() { return $localStorage.currentUser?.ulId; }, id : '@id' }, { update: { method: 'PUT' } }); });
这样不管什么时候切换用户,只要$localStorage.currentUser更新了,下一次请求BookResource时就会自动用最新的roleId和ulId,完全不需要手动刷新页面或者遍历更新Resource。
方案二:登录时手动更新Resource参数(备选)
如果你一定要在登录时程序化更新所有Resource的参数,可以把Resource的参数做成可修改的对象,同时提供更新方法。比如:
angular.module('app').factory('BookResource', function($resource, $localStorage) { // 单独维护参数对象 var resourceParams = { roleId: $localStorage.currentUser.roleId, ulId : $localStorage.currentUser.ulId, id : '@id' }; var bookResource = $resource('/rest/:roleId/ul/:ulId/book/:id', resourceParams, { update: { method: 'PUT' } }); // 暴露更新参数的方法 bookResource.updateParams = function() { resourceParams.roleId = $localStorage.currentUser.roleId; resourceParams.ulId = $localStorage.currentUser.ulId; }; return bookResource; });
然后在登录成功的回调里,调用这个方法:
// 登录成功后 BookResource.updateParams();
如果有多个Resource需要更新,可以把这个逻辑封装成一个公共服务,遍历所有注册的Resource并调用它们的updateParams方法。不过相比方案一,这个方法需要手动维护,不如动态函数省心。
为什么原来的代码不行?
你原来的写法里,roleId: $localStorage.currentUser.roleId是在工厂被Angular注入时立即求值的,相当于把当时的roleId值复制了一份存在Resource的配置里,之后$localStorage变化不会影响这个已经固定的值。而用函数的话,每次请求都会重新执行函数,拿到最新的$localStorage数据。
内容的提问来源于stack exchange,提问作者Thomas

