Angular双向数据绑定:Ajax请求后视图未即时更新问题
问题原因分析
这是因为jQuery的Ajax操作不在AngularJS的上下文环境中,AngularJS的变更检测机制(脏检查)无法自动感知到回调函数里对$scope的修改。
AngularJS会在自己封装的异步操作(比如$http、$timeout、指令的事件回调)完成后,自动触发$apply()来启动变更检测,同步更新视图。但jQuery的Ajax是原生的异步操作,AngularJS对它的回调没有监控,所以当你在success里修改$scope.titlelangnative时,Angular不知道数据已经变了,自然不会更新输入框。而你点击DOM元素时,可能触发了Angular的某些内置事件(比如焦点事件),间接触发了$apply(),这时候脏检查才发现$scope的变化,视图才会刷新。
解决方案
有两种常用的解决方式,推荐优先用第一种:
1. 替换jQuery Ajax为AngularJS自带的$http服务
$http是Angular官方提供的HTTP请求工具,它会自动处理变更检测,不用手动触发。
修改你的控制器代码:
angularFormsApp.controller('efController', ["$scope", "$window", "$routeParams", "$http", function efController($scope, $window, $routeParams, $http) { var siteRoot = dnn.getVar("sf_siteRoot", "/"); $http.get(siteRoot + "DesktopModules/MVC/Ycon/Item/GetDraft", { headers: sf.getModuleHeaders() // 替换beforeSend里的请求头设置 }) .then(function(response) { var result = response.data; // $http会自动解析JSON,无需手动调用JSON.parse $scope.titlelangnative = result.title_langNative; // 这里不需要额外操作,Angular会自动更新视图 }, function(error) { $("#gotobankloader").addClass('hidden'); alert('error'); }); }]);
2. 手动触发Angular的变更检测(如果必须用jQuery Ajax)
如果因为某些原因不能替换为$http,可以在修改$scope后手动调用$scope.$apply(),或者用$timeout包裹修改逻辑($timeout会自动触发$apply,还能避免在已经处于digest循环时调用$apply报错)。
方式一:使用$scope.$apply()
success: function (data, status, xhr) { var result = JSON.parse(data); $scope.$apply(function() { $scope.titlelangnative = result.title_langNative; }); }
或者直接在修改后调用:
success: function (data, status, xhr) { var result = JSON.parse(data); $scope.titlelangnative = result.title_langNative; $scope.$apply(); }
方式二:使用$timeout(更安全)
先在控制器里注入$timeout,然后修改回调:
angularFormsApp.controller('efController', ["$scope", "$window", "$routeParams", "$timeout", function efController($scope, $window, $routeParams, $timeout) { // ...其他代码 success: function (data, status, xhr) { var result = JSON.parse(data); $timeout(function() { $scope.titlelangnative = result.title_langNative; }); } // ...其他代码 }]);
内容的提问来源于stack exchange,提问作者Moslem7026
相关产品推荐
相关产品推荐

