2013-02-08 5 views
2

Угловое, похоже, сработало «открытым» состоянием Chrome (возможно, других браузеров) XMLHttpRequest во время фазы $ digest при его копировании. При доступе к полю XMLHttpRequest.status он вызывает исключение. Мой фактический прецедент не привязан к полю состояния; объект XMLHttpRequest является всего лишь одним членом другого объекта в массиве, который хранит I $.Обходное решение AngularJS DOM Exception

Так,

а) Если ANGULAR быть умнее о таких случаях и игнорировать исключение?
b) Есть ли способ иметь Угловые поля игнорирования или объекты при переваривании содержащих объекты?
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 

ответ

1

Вы должны использовать службу $http. (Пример 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; 
    }); 
} 

РЕДАКТИРОВАТЬ (не проверено): Контроллер использованием XMLHttpRequest: использованием event listeners вызвать $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> 

Пример:

+0

Спасибо, что я пробовал в первую очередь, но мне нужно получить промежуточные события из моего запроса (это загрузка), которую $ http не предоставляет. – darrinm

+0

См. Мой обновленный ответ –

+0

Еще раз спасибо. К сожалению, как упоминалось в моем вопросе, мой фактический случай более сложный, чем пример кода здесь. У меня есть массив объектов, каждый из которых имеет несколько свойств, одним из которых является объект XMLHttpRequest. Я ссылаюсь на XMLHttpRequest, поэтому я могу не только получить его статус, но и позвонить, например. abort().Направление, которое вы собираете, добавляет возрастающей сложности, поскольку большее количество состояний и функциональных возможностей соединяются с XMLHttpRequest на наблюдаемый объект. Я бы предпочел, чтобы общее решение позволяло безопасно включать ссылку на XMLHttpRequest в просмотренных объектах. – darrinm

0

Расставаться б мой вопрос:

b) Is there a way to have Angular ignore fields or objects when it is digesting containing objects?

Ответ да, оберните поле/объект с помощью функции, например .:

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

И Угловой будет игнорировать его, когда $ переваривания. Конечно, это предполагает, что вам нужно/нужно, чтобы его игнорировали. Изменения в этом поле/объекте не вызовут наблюдателей.

Смежные вопросы