我在Node Webkit中使用Angular和TingoDB(Mongo)作为单页面应用程序。但是我有一个我无法解决的奇怪问题。
当我使用对象文字(选项2)时,数据在html页面中正确显示。但是,更改代码以从数据库返回数据(选项1)后,结果不会出现在html页面上。我已将两种样式的数据转换为JSON字符串以证明一致性,然后使用angular.fromJSON返回一个对象。两种方法都在console.log中返回相同的JSON字符串,并且在任何人要求我将选项1或选项2注释掉之外,因此两者都没有同时运行。
我已经根据从TingoDB传递到console.log的数据复制了JSON字符串,并将其重新输入到下面的代码中,以确保在不更改任何其他代码的情况下,两个版本的数据之间没有差异,但是问题仍然存在。
任何人都可以阐明为什么会发生这种情况以及如何解决这个问题?
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>
答案 0 :(得分:0)
TingoDB是一个异步API,可以在后台运行而不会停止你的应用程序。这意味着同步代码没有时间等待答案,作为回报,它给出了未定义的。
在你的情况下,你做了一个异步调用,它正确地返回了内存的答案,但为时已晚,即使你的javascript有数据,DOM已经使用undefined更新了(试试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"