AngularJS中函数内赋值的$scope变量在外访问为undefined如何解决
问题原因
你遇到的问题本质是AngularJS中$http请求为异步执行,$scope.sourceList只有在请求成功的回调函数中才会被赋值,如果你在请求完成之前就调用saveAp,自然会拿到undefined。另外如果你的控制器存在嵌套作用域的情况,也可能因为原型继承的特性导致直接挂载在$scope上的变量被覆盖,出现访问不到的问题。
解决方案
1. 初始化变量默认值
在控制器初始化阶段给$scope.sourceList设置默认空值,避免出现undefined报错:
// 控制器代码最顶部添加 $scope.sourceList = [];
2. 调整调用逻辑,保证请求完成后再访问变量
如果你的业务逻辑是需要先加载数据再执行保存操作,可以把$http返回的Promise对外暴露,用链式调用保证执行顺序:
$scope.loadMoreDetails = function () { // 返回$http的Promise实例 return $http({ method: "GET", url: appConfig.apiUrl + "/results/" + $scope.resultId + "/details/" }).then(function (response) { $scope.sourceData = response.data.sources; $scope.sourceList = $scope.sourceData.split(', '); console.log($scope.sourceList); }, function (response) { $log.error(response); }); }; // 新增触发方法,先等数据加载完成再执行保存 $scope.handleSave = function() { $scope.loadMoreDetails().then(function() { $scope.saveAp(); }) } $scope.saveAp = function () { console.log($scope.sourceList) }
后续需要触发保存操作时,直接调用handleSave方法即可。
3. 页面初始化阶段提前加载数据
如果数据是页面加载完成就需要用到的,直接在控制器初始化阶段调用loadMoreDetails,保证用户触发保存操作前,变量已经完成赋值:
// 控制器初始化阶段直接调用 $scope.loadMoreDetails();
4. 解决嵌套作用域覆盖问题
如果你的控制器是嵌套在其他父控制器下的,建议把变量挂载到对象上,避免原型继承导致的变量覆盖问题:
// 初始化时定义统一的数据容器 $scope.dataStore = { sourceList: [] } // 赋值时修改对象属性 $scope.loadMoreDetails = function () { $http({ method: "GET", url: appConfig.apiUrl + "/results/" + $scope.resultId + "/details/" }).then(function (response) { $scope.sourceData = response.data.sources; $scope.dataStore.sourceList = $scope.sourceData.split(', '); }, function (response) { $log.error(response); }); }; // 访问时读取对象属性 $scope.saveAp = function () { console.log($scope.dataStore.sourceList) }
内容的提问来源于stack exchange,提问作者Kumara
相关产品推荐
相关产品推荐

