Почему мое представление AngularJS не обновляется после вызова AJAX с помощью Parse.com JavaScript SDK?
Вот мой взгляд
<div ng-repeat="blog in blogs">
<h3>{{blog.title}}</h3>
<h4>{{blog.post}}</h4>
</div>
Мой Код Контроллера:
demoApp.controller('myController', ['$scope', 'blogService', function ($scope,
blogService)
{
$scope.blogs = blogService.getBlogs();
}]);
Мой код на службе. Это включает в себя асинхронный вызов Parse.com JavaScript sdk.
this.getBlogs = function ()
{
var BlogPost = Parse.Object.extend("BlogPost");
var blogPost = new BlogPost();
var blogs = [];
var query = new Parse.Query(BlogPost);
query.find({
success: function(results) {
console.log(results[0].get("title"));
for (var i = 0; i < results.length; i++)
{
blogs.push(
{
title : results[i].get("title"),
post : results[i].get("post")
});
}
console.log(blogs);
},
error: function(error) {
alert("Error: " + error.code + " " + error.message);
}
});
return blogs;
}; });
Журнал консоли console.log(blogs);
отлично показывает возвращенные данные. Просто представление не обновляется после извлечения этого значения.
3 ответа:
Код в обратных вызовах выполняется "вне мира Angular", что означает, что цикл $digest не будет запущен и изменения не будут отражены в DOM.
Вам нужно использовать $apply :
$apply () используется для выполнения выражения в angular извне угловой каркас. (Например, из событий DOM браузера, библиотеки setTimeout, XHR или сторонних производителей). Потому что мы взываем к угловой каркас нам нужен для выполнения правильного объема жизни цикл из обработка исключений, выполнение вахт.
Введите
$rootScope
в вашу службу и, например:success: function(results) { $rootScope.$apply(function () { console.log(results[0].get("title")); for (var i = 0; i < results.length; i++) { blogs.push( { title : results[i].get("title"), post : results[i].get("post") }); } console.log(blogs); }); },
Ваш обратный вызов "success" выполняется асинхронно, и angular не знает, когда это произойдет. Чтобы сообщить angular об успешном обратном вызове, вы можете обернуть его в $ scope.$apply
success: function(results) { $scope.$apply(function() { console.log(results[0].get("title")); for (var i = 0; i < results.length; i++) { blogs.push( { title : results[i].get("title"), post : results[i].get("post") }); } console.log(blogs); }); }
Обещайте, что ваши услуги вернутся!
.factory('factoryReturningPromise', function (){ ... return query.find() .then(function(results){ ... // make sure the return value is a resolved promise return Parse.Promise.as(blog); }, function(error){ // we are here because of query error - return rejected promise return Parse.Promise.error(error); }); })Тогда вам нужно только обернуть его в локальный
$scope.$apply
внутри вашего контроллера:.controller('myController', function ($scope, factoryReturningPromise) { $scope.$apply(function(){ blogService.getBlogs() .then(function(blogs){ $scope.blogs = blogs; }, function (error) { ... and deal with errors ... show bad news to user etc }); }); })Таким образом, будут проверены только локальные циклы дайджеста со всеми часами.