Angular не видит изменения моего массива в представлении

Я использую angularjs с Node-webkit и создаю настольное приложение с nedb (как встроенная база данных).

Моя проблема в том, что когда я загружаю (через службу) список объектов из базы данных и пытаюсь показать их в представлении (используя ng-repeat), представление не может видеть загруженные данные (похоже, что оно не получает никаких Обновить)

Когда я ставлю статические данные:

$scope.levels  = [{_id:'abcd'},{_id:'efgh'}];

По мнению получить это без проблем.

Я провел некоторое исследование и похоже, что это что-то связано с $apply а также $digest...Я не уверен.

Вот мой код:

    //router
    .state('level', {
    url: '/level',
   templateUrl:'frontend/components/level/views/level.html',
                                                                         controller: 'LevelController'

                    })

Контроллер загружает данные из БД асинхронно:

levelModule.controller('LevelController', function($scope,$rootScope,LevelService) {

//  $scope.levels  = [{_id:'abcd'},{_id:'eff'}];
  $scope.levels  = [];

  LevelService.getAllLevels(function(lvs) {
    console.log("tous "+JSON.stringify(lvs));
    $scope.levels = lvs;
  });

Вот мой сервис:

levelModule.factory('LevelService', function(DB_URL) {
    var Datastore = require('nedb')
    , path = require('path');
    db = {};
    db.levels = new Datastore({ filename:DB_URL+'/levels.db',autoload: true });


            return  {

                    getAllLevels : function(callback) {
                                            db.levels.find({}, function (err, lvs) {
                                                if(err)
                                                            console.log(err);
                                                        else

                                                            callback(lvs);


                                            });
                    },

                    insertLevel: function(level,callback) {
                        db.levels.insert(level, function (err, lv) {
                            if(err)
                                        console.log(err);
                                    else
                            callback(lv);
                        });
                    },
                    upsertLevel: function(level,callback) {

                        db.levels.update({_id: level._id}, {_id: level._id,price: {t1:{},t2:{},t3:{}}}, { upsert: true }, function(err,numReplaced,lv){
                                if(err)
                                        console.log(err);
                                    else
                            callback(numReplaced,lv);
                        });

           }
        };

});

И наконец мой взгляд:

<table  class="table table-bordered table-hover">
     <tr ng-repeat="level in levels">
         <td>
           {{level._id}}
          </td>

         <td>
             <button ng-click="loadPrices(level)" type="button" class="btn btn-default" data-animation="am-fade-and-scale" data-template="frontend/components/level/views/level.edit.html" data-placement="center" bs-modal="modal">
                 <i class="fa fa-pencil-square-o"></i> Modifier
             </button>
         </td>
     </tr>
</table>

Любая помощь?

2 ответа

Решение

Вы используете коллбэк старой школы, который происходит за пределами дайджеста Angular. Хорошо, что вы заработали, вызвав $ apply, но вы должны попытаться изменить свой сервис, чтобы вернуть Обещание. Обещания - это угловой способ выполнения асинхронных операций.

Вы можете прочитать больше о них по адресу https://thinkster.io/a-better-way-to-learn-angularjs/promises и https://docs.angularjs.org/api/ng/service/$q.

Решается путем помещения $apply() в асинхронную функцию:

 LevelService.getAllLevels(function(lvs) {

    $scope.levels = lvs;
    $scope.$apply();
  });
Другие вопросы по тегам