You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AngularJS中Ajax获取的数据无法更新Holder服务问题求助

解决AngularJS中Ajax调用后Holder服务数据不更新的问题

你遇到的这个问题其实很典型——控制台能拿到正确数据,但视图就是不更新,核心原因是你用了jQuery的$.ajax,而它脱离了AngularJS的脏检查(digest)循环体系。AngularJS只会在自己管控的异步操作(比如$http、$timeout)完成后自动触发脏检查,更新视图;但jQuery的Ajax回调执行时,Angular完全不知道数据已经发生变化,所以Holder里的name虽然在内存中更新了,视图却没跟上。

下面给你两种可行的解决方案:

方案1:改用Angular原生的$http(推荐)

这是最符合Angular开发规范的做法,$http会自动处理脏检查,不需要额外操作。修改你的ChildCtrl代码如下:

var app = angular.module('sharing', []);
var root="http://xxx.xxx.x.xx:60/Api";

app.factory('Holder', function() {
    return { value: 0, name:"" };
});

app.controller('ChildCtrl', function($scope, Holder, $http) { // 注入$http服务
    $scope.Holder = Holder;
    $scope.increment = function() {
        $scope.Holder.value++;
        var jData1 = {
            BDMeetingId: "10003/2017"
        };
        console.log(JSON.stringify(jData1));
        
        $http({
            method: 'POST',
            url: root + "/Boardmeeting/BoardmeetingDetailsSevice",
            data: JSON.stringify(jData1),
            headers: {
                'Content-Type': 'text/plain'
            },
            crossDomain: true
        }).then(function(response) {
            var msg = response.data;
            console.log(msg);
            $scope.BMNo = msg.BMNo;
            $scope.Holder.name = $scope.BMNo;
            // 这里不需要手动触发脏检查,$http已经帮你处理了
        }, function(error) {
            // 可在这里添加错误处理逻辑
        });
    };
});

app.controller('ChildCtrl2', function($scope, Holder) {
    $scope.Holder = Holder;
    $scope.increment = function() {
        $scope.Holder.value++;
    };
});

方案2:如果必须用jQuery Ajax,手动触发脏检查

如果你因为某些原因一定要保留jQuery的$.ajax,那就在回调函数里手动告诉Angular数据更新了,有两种安全的方式:

方式A:使用$scope.$apply()

在success回调的最后加上$scope.$apply(),强制Angular执行一次脏检查:

success: function (msg) {
    k=msg;
    $scope.BMNo=k.BMNo;
    console.log(msg);
    $scope.Holder.name=$scope.BMNo;
    $scope.$apply(); // 手动触发脏检查,通知Angular更新视图
},

方式B:使用$timeout(更稳妥)

$timeout是Angular提供的服务,它会自动在Angular的循环里执行,避免$apply()可能引发的“digest already in progress”错误:

// 记得先在控制器里注入$timeout
app.controller('ChildCtrl', function($scope, Holder, $timeout) {
    // ...其他代码
    success: function (msg) {
        k=msg;
        $scope.BMNo=k.BMNo;
        console.log(msg);
        $timeout(function() {
            $scope.Holder.name=$scope.BMNo;
        });
    },
    // ...其他代码
});

额外小提示

你的index.html里有重复的<head>标签,虽然不影响功能,但建议修正一下,避免潜在的问题:

<!DOCTYPE html>
<html ng-app="sharing">
<head>
    <script data-require="angular.js@1.5.6" data-semver="1.5.6" src="https://code.angularjs.org/1.5.6/angular.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <script src="script.js"></script>
</head>
<body>
    <div ng-controller="ChildCtrl">
        <button ng-click="increment()" name="data1">+</button>{{Holder.value}}
    </div>
    <div ng-controller="ChildCtrl2">
        <h2>Second controller</h2>
        <button ng-click="increment()" name="data2">+</button>{{Holder.value}}
        <button ng-click="" name="data3">+</button>{{Holder.name}}
    </div>
</body>
</html>

内容的提问来源于stack exchange,提问作者Joe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:24:28