2

在 $digest 阶段复制它时,Angular 似乎被 Chrome(可能还有其他浏览器)XMLHttpRequest 的“打开”状态绊倒了。当访问 XMLHttpRequest.status 字段时,它会引发异常。我的实际用例没有绑定到状态字段;XMLHttpRequest 对象只是我 $watch 的数组中另一个对象的一个​​成员。

所以,

a) Angular 是否应该更聪明地处理这种情况并忽略异常?
b)有没有办法让Angular在消化包含对象时忽略字段或对象?
c) 其他解决方法建议?

这是一个例子。这个 HTML+Javascript ( JSFiddle ):

<div ng-app ng-controller="TestCtrl">
  <h2>XMLHttpRequest.status: {{ xhr.status }}</h2>
</div>

function TestCtrl($scope) {
  $scope.xhr = new XMLHttpRequest();
  $scope.xhr.open('POST', 'http://localhost:8000/api/medias', true);
}

导致此错误:

Error: INVALID_STATE_ERR: DOM Exception 11
Error: An attempt was made to use an object that is not, or is no longer, usable.
at eval (eval at Jb (http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.3/angular.min.js:74:389), <anonymous>:16:4)
at d.fn.x.assign (http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.3/angular.min.js:63:120)
at Object.j (http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.3/angular.min.js:52:126)
at Object.e.$digest (http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.3/angular.min.js:84:286)
at Object.e.$apply (http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.3/angular.min.js:86:469)
at http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.3/angular.min.js:15:396
at Object.d [as invoke] (http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.3/angular.min.js:26:401)
at pb (http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.3/angular.min.js:15:317)
at jc (http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.3/angular.min.js:15:178)
at http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.3/angular.min.js:159:424 angular.min.js:60
4

2 回答 2

1

您需要使用该$http服务。(示例 99% 来自 Angular 文档示例)

控制器:

function TestCtrl($http, $scope) {
  $scope.xhr = {status : undefined};

  $http.post('http://localhost:8000/api/medias', {params:{'go':'here'}})
    .success(function(data, status) {
      $scope.xhr.status = status;
    })
    .error(function(data, status) {
      $scope.xhr.status = status;
    });
}

编辑(未测试):使用XMLHttpRequest的控制器: 使用事件侦听器调用$apply

function TestCtrl($http, $scope) {
   $scope.xhr = {status : undefined};

   var xhr = new XMLHttpRequest();

   xhr.addEventListener('progress', function(event) {
     var progress = event['something']//get what you need from the event..
      $scope.$apply(function() {
        $scope.xhr.progress = progress;
      });
   }, false);

   xhr.open('POST', 'http://localhost:8000/api/medias', true);
}

模板:

<div ng-app ng-controller="TestCtrl">
  <h2>XMLHttpRequest.status: {{ xhr.status }}</h2>
  <h2>XMLHttpRequest.status: {{ xhr.progress}}</h2>
</div>

例子:

于 2013-02-08T22:31:10.637 回答
0

对于我的问题的 b 部分:

b)有没有办法让Angular在消化包含对象时忽略字段或对象?

答案是肯定的,用函数包装字段/对象,例如:

$scope.getXhr = function () { return xhr; }

Angular 在 $digesting 时会忽略它。当然,这假定您希望/需要忽略它。对该字段/对象的更改不会触发观察者。

于 2013-02-20T22:44:05.067 回答