Я использую элемент ng-repeat для отображения списка элементов. Каждый элемент имеет некоторые объекты Parse.Pointer, которые ссылаются на другие объекты. В моем шаблоне, когда я хочу отобразить значение из объекта, на который ссылается, значение отображается только тогда, когда я сначала перехожу на другую вкладку своего ионного приложения, а затем возвращаюсь на вкладку, где я хочу отображать эти значения.
Это мой призыв к списку элементов:
function getFragments(limit){
var deferred = $q.defer();
var query = new Parse.Query(Fragment);
query.limit(limit);
query.descending('createdAt');
query.find({
success: function(results){
deferred.resolve(results);
error: function(error){
deferred.reject(error);
}
});
return deferred.promise;
}
вот как я присваиваю значения пространству $:
Fragment.getFragments(20).then(function(fragments){
$scope.fragments=fragments;
});
и это как я отображаю значение объекта, у которого есть указатель на объект (событие - это указатель, имя - переменная из объекта события):
<ion-item ng-repeat="fragment in fragments">
<h3>{{fragment.event.name}}</h3>
Каждое значение каждого объекта в списке также имеет свойство get, определенное следующим образом:
Fragment.prototype.__defineGetter__('event', function(){
return this.get('event');
});
После некоторых проблем я нашел несколько решений. Я опишу 2.
Для каждого фрагмента в массиве выберите объект для указателя. При успешном извлечении объекта вызов $ scope. $ Apply() для уведомления об изменениях в области.
Fragment.getFragments(20).then(function(fragments){
angular.forEach(fragments, function(fragment){
if(fragment.event){
promises.push(fragment.event.fetch({
success: function(){
$scope.$apply();
}
}));
}
});
Но поскольку я извлекаю несколько объектов из указателей для каждого фрагмента, я хотел использовать обещания и вызывать $scope.$apply()
когда все обещания разрешены.
var promises = [];
if(fragment.user){
promises.push(fragment.user.fetch());
}
if(fragment.artist){
promises.push(fragment.artist.fetch());
}
$q.all(promises).then($scope.$apply());
Это дает мне сообщение о том, что $digest
уже выполняется, поэтому я предполагаю, что $q.all
уже запускает $digest
. Поэтому просто использование $q.all(promise)
решает проблему.
Когда вы запрашиваете фрагменты, выбирайте все объекты для указателей перед тем, как разрешить обещание.
function getFragments(limit) {
var deferred = $q.defer();
var query = new Parse.Query(Fragment);
query.limit(limit);
query.descending('createdAt');
query.find({
success: function (fragments) {
var promises = [];
angular.forEach(fragments, function(fragment){
if(fragment.user){
promises.push(fragment.user.fetch());
}
if(fragment.artist){
promises.push(fragment.artist.fetch());
}
});
$q.all(promises).then(function(){
deferred.resolve(fragments);
});
},
error: function (error) {
console.log('log error');
}
});
return deferred.promise;
}
На мой взгляд, второе решение является лучшим, потому что лучше оставить логику данных вне контроллера и не использовать $ scope в логике данных.
моя первая догадка без фактического запуска кода будет заключаться в том, что угловой не знает, что что-то было обновлено.
вам нужно сообщить Angular, что что-то было обновлено и что он должен запустить $digest
или $apply
чтобы обновить его область тоже.
$scope.$apply()
- это способ решить эту проблему. Спасибо! (Я опишу это решение в моем ответе)