在 nwjs (node-webkit) 中将数据从 nodejs 传递到 angular 的正确方法
Correct way to pass data from nodejs to angular in nwjs (node-webkit)
已解决:下面的代码现在适用于任何需要它的人。
- 创建查询数据库和 returns 查询结果的 Angular 工厂。
- 将这些查询结果传递到我的控制器的 $scope
- 在我的视图中呈现 $scope 变量的结果 (html)
挑战:
因为这是针对 node-webkit (nwjs) 应用程序的,所以我尝试在不使用 express、设置 api 端点并使用 $http 服务 return 查询结果的情况下执行此操作。我觉得应该有更多的 eloquent 方法通过直接将数据从 nodejs 传递到 angular 控制器来做到这一点。以下是我尝试过但没有奏效的方法。
数据库: 下面的代码用于 nedb 数据库。
我的已更新 控制器
app.controller('homeCtrl', function($scope,homeFactory){
homeFactory.getTitles().then(function(data){
$scope.movieTitles = data;
});
});
我的更新工厂:
app.factory('homeFactory', function($http,$q) {
return {
getTitles: function () {
var deferred = $q.defer();
var allTitles = [];
db.find({}, function (err, data) {
for (var i = 0, len = data.length; i < len; i++) {
allTitles.push(data[i].title)
}
deferred.resolve(allTitles);
});
return deferred.promise;
}
}
});
HTML
<script>
var Datastore = require('nedb');
var db = new Datastore({ filename: './model/movies.db', autoload: true });
</script>
<--shows up as an empty array-->
<p ng-repeat="movie in movieTitles">{{movie}}</p>
部分答案:我能够通过将所有代码移动到控制器中来让它工作。现在有人如何重构以下内容以使用工厂清理代码吗?
更新控制器($scope.movietitles 正在使用正确的数据更新视图):
$scope.movieTitles = [];
$scope.getMovieTitles = db.find({},function(err,data){
var arr = [];
for (var i = 0, len = data.length; i < len; i++){
arr.push(data[i].title)
}
$scope.movieTitles = arr;
$scope.$apply();
});
所以您原来的 homeFactory
的问题是 db.find
是异步发生的。虽然你可以很好地使用回调,但我认为最好用 $q
.
包装它们
app.service('db', function ($q) {
// ...
this.find = function (query) {
var deferred = $q.defer();
db.find(query, function (err, docs) {
if (err) {
deferred.reject(err);
} else {
deferred.resolve(docs);
}
});
return deferred.promise;
};
// ...
});
一旦你开始像这样包装非Angular代码,它就会使界面保持一致。
app.service('homeFactory', function (db) {
this.getAllTitles = function () {
return db.find({}).then(function (docs) {
return docs.map(function (doc) {
return doc.title;
});
});
};
});
控制器看起来像:
app.controller('homeCtrl', function ($scope, homeFactory) {
homeFactory.getAllTitles().then(function (titles) {
$scope.movieTitles = titles;
});
});
已解决:下面的代码现在适用于任何需要它的人。
- 创建查询数据库和 returns 查询结果的 Angular 工厂。
- 将这些查询结果传递到我的控制器的 $scope
- 在我的视图中呈现 $scope 变量的结果 (html)
挑战: 因为这是针对 node-webkit (nwjs) 应用程序的,所以我尝试在不使用 express、设置 api 端点并使用 $http 服务 return 查询结果的情况下执行此操作。我觉得应该有更多的 eloquent 方法通过直接将数据从 nodejs 传递到 angular 控制器来做到这一点。以下是我尝试过但没有奏效的方法。
数据库: 下面的代码用于 nedb 数据库。
我的已更新 控制器
app.controller('homeCtrl', function($scope,homeFactory){
homeFactory.getTitles().then(function(data){
$scope.movieTitles = data;
});
});
我的更新工厂:
app.factory('homeFactory', function($http,$q) {
return {
getTitles: function () {
var deferred = $q.defer();
var allTitles = [];
db.find({}, function (err, data) {
for (var i = 0, len = data.length; i < len; i++) {
allTitles.push(data[i].title)
}
deferred.resolve(allTitles);
});
return deferred.promise;
}
}
});
HTML
<script>
var Datastore = require('nedb');
var db = new Datastore({ filename: './model/movies.db', autoload: true });
</script>
<--shows up as an empty array-->
<p ng-repeat="movie in movieTitles">{{movie}}</p>
部分答案:我能够通过将所有代码移动到控制器中来让它工作。现在有人如何重构以下内容以使用工厂清理代码吗?
更新控制器($scope.movietitles 正在使用正确的数据更新视图):
$scope.movieTitles = [];
$scope.getMovieTitles = db.find({},function(err,data){
var arr = [];
for (var i = 0, len = data.length; i < len; i++){
arr.push(data[i].title)
}
$scope.movieTitles = arr;
$scope.$apply();
});
所以您原来的 homeFactory
的问题是 db.find
是异步发生的。虽然你可以很好地使用回调,但我认为最好用 $q
.
app.service('db', function ($q) {
// ...
this.find = function (query) {
var deferred = $q.defer();
db.find(query, function (err, docs) {
if (err) {
deferred.reject(err);
} else {
deferred.resolve(docs);
}
});
return deferred.promise;
};
// ...
});
一旦你开始像这样包装非Angular代码,它就会使界面保持一致。
app.service('homeFactory', function (db) {
this.getAllTitles = function () {
return db.find({}).then(function (docs) {
return docs.map(function (doc) {
return doc.title;
});
});
};
});
控制器看起来像:
app.controller('homeCtrl', function ($scope, homeFactory) {
homeFactory.getAllTitles().then(function (titles) {
$scope.movieTitles = titles;
});
});