Угловой контроллер не отображает данные из JSON

Я использую Angular и TingoDB (Mongo) внутри Node Webkit для одностраничного приложения. Однако у меня есть странная проблема, которую я не смог решить.

Когда я использую литерал объекта (вариант 2), данные корректно отображаются на html-странице. Однако при изменении кода для возврата данных из базы данных (вариант 1) результаты не отображаются на html-странице. Я преобразовал оба стиля данных в строку JSON, чтобы доказать согласованность, а затем использовал angular.fromJSON, чтобы вернуть объект. Оба метода возвращают одну и ту же строку JSON в console.log, и, прежде чем кто-либо спросит, я закомментировал вариант 1 или 2, поэтому оба они не работают одновременно.

Я скопировал строку JSON, основанную на данных, переданных из TingoDB, в console.log и повторно ввел ее в приведенный ниже код, чтобы убедиться, что между двумя версиями данных не было никаких различий без изменения какого-либо другого кода, но проблема по-прежнему сохраняется.

Может кто-нибудь пролить свет на то, почему это происходит и как это исправить?

var app = angular.module('myApp', []);
var Engine = require('tingodb')(),
    assert = require('assert');

var db = new Engine.Db('./db', {});
var collection = db.collection("clean.db");

app.controller('tingoDataCtrl', ['$scope', function($scope) {



     function getData(callback) {
        //Option 1
          collection.find().toArray(function(err, docs){
                callback (JSON.stringify(docs));
           });

          //Option 2
           var docs = [
               {name:"tingo1", description:"56",_id:2},
               {name:"tingo2", description:"33",_id:3},
               {name:"tingo3", description:"22",_id:4},
               {name:"tingo4", description:"76",_id:5},
               {name:"tingo5", description:"99",_id:6}
           ];   
           callback (JSON.stringify(docs));
  }

    function info(b) {
        // I'm the callback
        console.log(b);
        $scope.items = angular.fromJson(b)
    }

    getData(info);

}]); 

И HTML

<body ng-app="myApp" id="main">

<div class="page page-data ng-scope">


    <section class="panel panel-default" ng-controller="tingoDataCtrl">
    <div class="panel-heading"><span class="glyphicon glyphicon-th"></span> Tingo Data</div>

        <table class="table">
            <thead>
            <th class="col-md-4">
              Name
            </th>
            <th class="col-md-8">
              Description
            </th>
            <th class="col-md-8">
              ID
            </th>
            <th></th>
            <tr>
            </tr>

            </thead>
            <tbody>
            <!-- <tr class="reveal-animation" ng-repeat="item in items | filter:query"> -->
            <tr ng-repeat="item in items | filter:query">
              <td>{{item.name}}</td>
              <td>{{item.description}}</td>
              <td>{{item._id}}</td>

            </tr>
            </tbody>
        </table>
    </section>
</div>
<script src="js/tingo_problem.js"></script>
 </body>

1 ответ

TingoDB - это асинхронный API, который будет работать в фоновом режиме без остановки вашего приложения. Это означает, что у синхронного кода нет времени ждать ответа, а взамен он дает неопределенное.

В вашем случае вы выполнили асинхронный вызов, и он правильно возвращает ответ в память, но слишком поздно, DOM уже обновлен с неопределенным, даже если ваш javascript имеет данные (попробуйте console.log, чтобы увидеть, что это было там).

В Angular есть способ принудительно обновить DOM новыми элементами контроллера. это называется $apply. И лучший способ использовать его, чтобы избежать неожиданного поведения:

function info(b) {
    // I'm the callback
    console.log(b);
    $scope.items = angular.fromJson(b);
    if (!$scope.$$phase) {
       $scope.$apply(); //forces update the view
    }
}//$scope is NECESARY to be defined in the controler, avoid using it with "ControlerAs"
Другие вопросы по тегам