Обещание массива с PouchDB и AngularJs ng-repeat

Я читаю allDocs() из базы данных PouchDB в переменную AngularJS:

var db = pouchService.db;
$scope.recordlist = db.allDocs({startkey: 'move_', endkey: 'move_\uffff', include_docs: true});
console.log($scope.recordlist);

Я заметил, что он возвращает обещание, и когда я пытаюсь прочитать массив (и свойства объектов внутри массива) с помощью ng-repeat, он фактически не может получить доступ к результатам, я думаю, потому что они глубоко вложены.

<div class="row msf-row" 
     ng-repeat="record in recordlist | filter: shouldShow" 
     ng-class="{ 'msf-cancelled': record.cancelled, 'msf-commented' : record.comment}">
       <div class="col-md-1">{{record.time}}</div>
</div>

Есть ли способ превратить это обещание в простой массив объектов?

введите здесь описание изображения

У меня также загружен LoDash в приложение, я не знаю, может ли это быть полезным.


person Eric Mitjans    schedule 24.09.2015    source источник


Ответы (2)


Назначить массив после выполнения промиса (или показать ошибку, если произошла ошибка):

$q.when(db.allDocs({startkey: 'move_', endkey: 'move_\uffff', include_docs: true}))
  .then(function (recordlist) {
    $scope.recordList = recordList;
    console.log($scope.recordlist);
  })
  .catch(function (error) {
    console.error(error);
  });

Обновление: Как отметил Мэтт в комментариях, если вы не используете angular-pouch angular-pouchdb, вам нужно будет обернуть действие в $scope.$apply(), чтобы запустить цикл дайджеста, или сначала преобразовать обещание в угловое обещание с помощью $q.when(). Я думаю, что преобразование обещания в угловое обещание также позаботится об ошибках регистрации, но вы всегда должны обрабатывать ошибки (показывать пользователю сообщение). Конечно, вы можете сделать это с помощью глобального обработчика ошибок.

person felixfbecker    schedule 24.09.2015
comment
Это не то, как я бы сделал это в angular, поскольку pouchDB не транслируется напрямую в промисы angular. - person Matt Way; 25.09.2015
comment
Он дает обещания, совместимые с Promises/A+, что намного больше, чем вам нужно для этого простого случая. Я бы преобразовал его только в том случае, если бы хотел передать его какой-либо функции Angular, например, свойству разрешения для контроллеров. Но в данном случае не нужно. - person felixfbecker; 25.09.2015
comment
Нет, опять же, это совершенно неправильно и не имеет ничего общего с возможностями промисов. Обещания Angular встраиваются прямо в цикл дайджеста, а pouchDB — нет. Это означает, что для того, чтобы ваша строка $scope.recordList = recordList; работала, вам нужно включить $scope.$apply(). - person Matt Way; 25.09.2015
comment
@MattWay, я использую оболочку angular-pouch, чтобы решить эту проблему, вероятно, поэтому ответ от freshfilicio сработал. Поэтому я думаю, что вы оба правы.. - person Eric Mitjans; 25.09.2015
comment
@MattWay Я ничего не отрицал. Вы правы, я обновил свой ответ. - person felixfbecker; 25.09.2015

То, что вы делаете, - это доступ к обещанию, а не результаты обещания. Хотя allDocs действительно возвращает обещание, это не угловое обещание, поэтому вы также должны обернуть обещание в when, чтобы получить фактическое угловое обещание.

var pouchPromise = db.allDocs({startkey: 'move_', endkey: 'move_\uffff', include_docs: true});
$q.when(pouchPromise).then(function(recordList){
    $scope.recordList = recordList;
    console.log($scope.recordlist);
});

Я бы прочитал о том, как работают промисы здесь.

Следует отметить, что этот метод использования pouch описан в фактических документах pouchDB здесь: http://pouchdb.com/api.html

Конкретно:

Используете ионный/угловой? Вы можете обернуть обещания PouchDB в $q.when(). Это уведомит Angular об обновлении пользовательского интерфейса, когда обещание PouchDB будет разрешено.

Это позволит вам избежать использования $scope.$apply() при работе с асинхронной природой не угловых промисов.

person Matt Way    schedule 24.09.2015