#javascript #angularjs
#javascript #angularjs
Вопрос:
У меня есть фабрика, которая возвращает объект, который я хочу отобразить во внешнем интерфейсе. Существует какое-то странное поведение (по крайней мере, для меня), когда я устанавливаю переменную следующим образом:
Я установил переменную ‘returnObject’ в начале контроллера, а затем позже назначаю ее в функции, которую выводит factory:
module.factory("MyFactory", function ($http, $timeout, $cookies) {
var returnObject = {};
var myFunction = function(response) {
// un-coomment this and it doesn't work
// var test = {1: 'test 2'};
// returnObject = test;
// this works
returnObject[1] = 'test';
}
var poller = function() {
$http.get('data.json').then(function(response) {
$timeout(poller, 5000);
myFunction(response);
});
return returnObject;
};
return {
unreadMessagePoller: poller,
};
});
app.controller('MainCtrl', MainCtrl);
function MainCtrl($scope, PollingService) {
// poll for unread messages
$scope.test = PollingService.unreadMessagePoller();
};
Если я вывожу переменную $scope в своем шаблоне, я вижу объект, как и ожидалось. Однако, если я не буду комментировать следующие строки:
var test = {1: 'test 2'};
returnObject = test;
Кажется, что область действия не привязана, а внешний вывод пуст. Я просто не понимаю!
Я создал плунжер, чтобы продемонстрировать проблему.
https://plnkr.co/edit/feVaotKCE9w2uQLJ
Обновить:
Вот еще один плунжер, другой подход к тому же поведению, мне кажется, это ошибка:
Ответ №1:
$scope.test = PollingService.unreadMessagePoller();
Возвращает исходный объект var returnObject = {};
Код:
$http.get('data.json').then(function(response) {
returnObject[1] = 'test';
});
Изменяет содержимое исходного объекта.
С другой стороны, код:
$http.get('data.json').then(function(response) {
var test = {1: 'test 2'};
returnObject = test;
});
Заменяет ссылку на объект на заводе новой ссылкой на объект.
Поскольку контроллер имеет исходную ссылку на объект, он не видит измененную ссылку на объект.
Именно так работает JavaScript.
Честно говоря, я избегаю метода возврата пустого объекта и последующего заполнения содержимого, когда данные поступают с сервера. Этот метод был популярен на заре AngularJS, но теперь новые API возвращают обещания, а не пустые объекты, которые мутируют.
Комментарии:
1. Выглядит ли это лучше с promise: plnkr.co/edit/Sm8eDHtpDaIShFf1 — На самом деле я уже пытался добавить обещание, но я добавил его в функцию, которая вызывается основной функцией, которую предоставляет служба!
2. Обещания ES6 не интегрированы с фреймворком AngularJS и его циклом дайджеста. AngularJS изменяет обычный поток JavaScript, предоставляя свой собственный цикл обработки событий. Это разбивает JavaScript на контекст выполнения классического и AngularJS. Только операции, которые применяются в контексте выполнения AngularJS, выиграют от привязки данных AngularJS, обработки исключений, просмотра свойств и т. Д.
3. Я все еще не знаю, как перезаписать объект, не используя его как ссылку — возможно, angular.copy()? На каждой итерации содержимое объекта может меняться, я подумал, что вместо поиска различий и их удаления самым быстрым и простым подходом было бы выполнить одно назначение для удаления предыдущих данных объекта?
4.
$resource
Служба используетangular.copy
для заполнения содержимого объекта $resource, когда данные поступают с сервера. Объект $resource также имеет свойство с именем$promise
, которое содержит обещание, возвращаемое службой $http.