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();
});