2

Angular は、コピー中の $digest フェーズ中に Chrome の (おそらく他のブラウザも) XMLHttpRequest の「オープン」状態によってつまずくようです。XMLHttpRequest.status フィールドにアクセスすると、例外が発生します。私の実際のユースケースはステータスフィールドにバインドされていません。XMLHttpRequest オブジェクトは、$watch する配列内の別のオブジェクトの 1 つのメンバーにすぎません。

そう、

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ます。(Angular ドキュメントの例から 99% 持ち上げた例)

コントローラ:

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

EDIT(テストされていません):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 に答える