无法在ajax调用中设置Angular范围变量

时间:2016-02-10 21:17:02

标签: angularjs ajax scope

var req = {
            "RequestId": $scope.$parent.req_id,
            "RequestDate": new Date(),
            "RequestDetails": $scope.$parent.details
        };

$scope.req_result = "test";

$.ajax({
            type: "POST",
            url: 'http://localhost:49358/api/myClasses/PostRequest',
            data: JSON.stringify(req),
            contentType: "application/json;charset=utf-8",
            processData: true,
            success: function (data, status, xhr) {
                console.log("The result is : " + status);
                $scope.req_result = "Post succeeded";
            },
            error: function (xhr) {
                $scope.req_result = "ERROR: " + xhr.responseText
            }
        });

范围变量$ scope.req_result未设置,因此当我尝试在html视图页面上显示它时:

<span>{{req_result}}</span>

显示默认值。某种方式ajax正在做什么是不知道角度

1 个答案:

答案 0 :(得分:5)

从非角度上下文修改范围变量后,您忘记通过调用$scope.$apply()来启动摘要周期。

success: function (data, status, xhr) {
    $scope.req_result = "Post succeeded";
    $scope.$apply();
},
error: function (xhr) {
    $scope.req_result = "ERROR: " + xhr.responseText
    $scope.$apply();
}

Angular通过创建名为“ watchers ”的内容来更新神奇视图。当你执行{{ someScopeVariable }}时,Angular正在为该范围变量创建观察者。就像通过执行

以编程方式创建观察者一样
$scope.$watch('someScopeVariable', function myListenerFunction() {
    // When someScopeVariable changes, do this
});

观察者与名为摘要周期的东西齐头并进。从Angular内的不同地方,例如$ timeout回调或$ http.then()回调等,Angular从$ rootScope调用摘要周期。这基本上是通过范围内的所有观察者,如果观察的值已经改变,则调用上面的 myListenerFunction 之类的监听器函数。

重要的是Angular在内部触发了这个摘要周期。所以,当你使用jQuery中的$ .ajax()时,你会错过这个。您可以更改正在监视的范围变量

{{req_result}}

但是,没有观察者知道它。 $scope.$apply()通过从根范围启动摘要周期,确保所有观察者都知道此更改。

<强> BUT

更好的解决方案是使用Angular的内部$ http服务,该服务可用于发出XHR请求,而Angular会在调用回调函数时自动触发摘要周期。

var req = {
            "RequestId": $scope.$parent.req_id,
            "RequestDate": new Date(),
            "RequestDetails": $scope.$parent.details
        };

$scope.req_result = "test";

$http
    .post('http://localhost:49358/api/myClasses/PostRequest', req)
    .then(
        function () {
            $scope.req_result = "Post succeeded";
        }, 
        function () {
            $scope.req_result = "ERROR";
        }
    );