3

已解决:下面的代码现在适用于任何需要它的人。

  1. 创建一个查询数据库并返回查询结果的 Angular 工厂。
  2. 将这些查询结果传递到我的控制器的 $scope
  3. 在我的视图中渲染 $scope 变量的结果 (html)

挑战: 因为这是针对 node-webkit (nwjs) 应用程序,所以我尝试在不使用 express、设置 api 端点和使用 $http 服务返回查询结果的情况下执行此操作。我觉得应该有一种更雄辩的方式来做到这一点,将数据从 nodejs 直接传递到角度控制器。以下是我尝试过的,但没有奏效。

数据库: 以下代码用于 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>
4

2 回答 2

1

所以你原来的问题homeFactorydb.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;
  });
});
于 2015-07-27T00:45:11.297 回答
1

部分答案: 我能够通过将所有代码移动到控制器中来使其工作。现在有人如何重构以下内容以使用工厂清理代码?

更新的控制器($scope.movi​​etitles 正在使用正确数据更新视图):

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

    });
于 2015-07-26T23:41:38.647 回答