AngularJS中无法在$http.get.then中修改$scope变量问题求助
解决AngularJS中$http异步请求后$scope变量未及时更新的问题
这个问题我太熟悉了,本质是异步操作的执行顺序搞的鬼!
为什么会出现这个现象?
你写的$http.get是异步请求——浏览器发送请求后不会原地等待响应返回,而是直接继续执行后续的同步代码。所以你的两次console.log都是在请求还没完成、then里的回调函数还没执行的时候就跑了,这时候$scope.loaded_view自然还是初始值"before"。
具体解决办法
办法1:把依赖更新后变量的逻辑放进then回调里
如果你的代码需要用到更新后的loaded_view,直接把逻辑挪到then的回调函数中就行,这是最直接的方式:
$scope.loaded_view = "before"; $scope.getView = function(name) { $http.get(chrome.extension.getURL("/views/" + name + ".html")).then(function(response, stat, xhr) { $scope.loaded_view = "after"; console.log($scope.loaded_view); // 这里会输出"after" // 所有需要用到更新后变量的逻辑都放在这个回调里 }); } $scope.getView('target');
办法2:用$watch监听变量变化
如果不想把所有代码都塞进回调里,可以用AngularJS的$watch来监听loaded_view的变化,当变量更新时自动触发对应逻辑:
$scope.loaded_view = "before"; // 监听loaded_view的变化 $scope.$watch('loaded_view', function(newVal, oldVal) { if(newVal !== oldVal) { console.log($scope.loaded_view); // 变量更新后会触发这里,输出"after" } }); $scope.getView = function(name) { $http.get(chrome.extension.getURL("/views/" + name + ".html")).then(function(response, stat, xhr) { $scope.loaded_view = "after"; }); } $scope.getView('target');
办法3:使用async/await(需AngularJS 1.6+支持)
如果你的项目用了较新版本的AngularJS,可以把函数改成异步函数,用await等待请求完成,让代码逻辑更线性:
$scope.loaded_view = "before"; $scope.getView = async function(name) { await $http.get(chrome.extension.getURL("/views/" + name + ".html")); $scope.loaded_view = "after"; console.log($scope.loaded_view); // 输出"after" // 若遇到视图未自动更新的情况,可手动触发 digest 循环: // $scope.$apply(); } $scope.getView('target');
关键提醒
所有依赖异步操作结果的代码,都要放在异步回调内部或者等待异步完成之后执行,不能直接写在异步调用的外面,否则拿到的永远是变量的初始值。
内容的提问来源于stack exchange,提问作者user1938361
相关产品推荐
相关产品推荐

