Cannot set Angular scope variable from within ajax call

主宰稳场 提交于 2019-12-12 01:40:08

问题


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
            }
        });

The scope variable $scope.req_result does not get set so when I attempt to display it on the html view page:

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

it displays the default value. Somehow what ajax is doing is not known to angular


回答1:


You forgot to initiate the digest cycle by calling $scope.$apply() after you modify the scope variable from non-angular context.

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

Angular does the magical view updates by creating something called "watchers". When you do {{ someScopeVariable }}, Angular is creating watcher for that scope variable. Just as when you programmatically create a watcher by doing

$scope.$watch('someScopeVariable', function myListenerFunction() {
    // When someScopeVariable changes, do this
});

Watchers go hand-in-hand with something called digest cycle. From different places within Angular, e.g. $timeout callback, or $http.then() callback etc., Angular invokes the digest cycle from the $rootScope. This is basically going through all the watchers in the scope and if the value being watched has changed, invoke the listener function like the myListenerFunction above.

Important thing is Angular is triggering this digest cycle internally. So, when you use $.ajax() from jQuery, you are missing this. You change the scope variable that are being watched because you did

{{req_result}}

but, no watchers know about it. $scope.$apply() makes sure all the watchers know about this change by initiating a digest cycle from the root scope.

BUT

A better solution to your issue would be to use Angular's internal $http service which can be used to make XHR request and Angular automatically triggers digest cycle when you callback functions are invoked.

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";
        }
    );


来源:https://stackoverflow.com/questions/35326062/cannot-set-angular-scope-variable-from-within-ajax-call

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!