【问题标题】:How to pass content from service to another service to controller with callbacks after it has been parsed?解析后如何通过回调将内容从服务传递到另一个服务到控制器?
【发布时间】:2015-08-05 20:37:52
【问题描述】:

我有一个使用回调函数将内容传递给控制器​​的服务:

  angular.module('piApp').service("dataRetrievalService", function () {

  function getContents(callback) {
      //Converter Class 
      var fs = require("fs");
      var Converter = require("csvtojson").Converter;
      var fileStream = fs.createReadStream("order.csv");
      //new converter instance 
      var converter = new Converter({ constructResult: true });
      //end_parsed will be emitted once parsing finished 
      converter.on("end_parsed", function (jsonObj) {
          console.log(jsonObj); //here is your result json object 
          //getResult(jsonObj)
          callback(jsonObj);
      });
      //read from file 
      fileStream.pipe(converter);
  }

  // public api
  return {
      getContents: getContents
  }
})

此服务使用csvtojson node module 从 csv 文件中获取 JSON 格式的内容。这是使用它的控制器:

angular.module('piApp').controller('homeController', ['$scope', 'dataRetrievalService', function ($scope, dataRetrievalService) {

     dataRetrievalService.getContents(function(contents) {
     $scope.result = contents;
     });

}]);

我想知道如何将解析逻辑正确地移动到另一个注入dataRetrievalService 的服务中,并在解析后仍将 csv 文件的内容发送到控制器。

所以我的新csvService 将是

angular.module('piApp').service("csvService", function () {
// public methods

function getCsvAsJSON(callback) {
    //Converter Class 
    var fs = require("fs");
    var Converter = require("csvtojson").Converter;
    var fileStream = fs.createReadStream("Contents/Product Groups/orderTest2.csv");
    //new converter instance 
    var converter = new Converter({ constructResult: true });
    //end_parsed will be emitted once parsing finished 
    converter.on("end_parsed", function (jsonObj) {
        console.log(jsonObj); //here is your result json object 
        callback(jsonObj);
    });
    //read from file 
    fileStream.pipe(converter);
}


// public api
return {
    getCsvAsJSON: getCsvAsJSON
}
})

我的dataRetrievalService 变成了类似

angular.module('piApp').service("dataRetrievalService", ['csvService', function (csvService) {

    function getContents() {

        csvService.getContents(function (contents) {
            this.result = contents; //should I be using another callback here instead?
        });
    }
    // public api
    return {
        getContents: getContents
    }
}])

我正在努力想象这将如何工作,以便我将第二个回调传递给控制器​​并仍然获得所需的内容。解析后如何将内容从服务传递到服务到控制器?

非常感谢您的宝贵时间。如果您需要任何其他信息或者我不清楚,请告诉我。

这个问题是this previous post的延伸

【问题讨论】:

  • 那么dataRetrievalService 服务会做什么呢?只需拨打csvService.getCsvAsJSON 或其他电话?
  • @dfsq 是的,这两个服务中都会有其他功能。 csvService 将有不同的选项,例如csvService.getCsvAsArraydataRetrievalService 将接受参数,以便它知道要为哪个视图获取数据,以及是否应该对其进行排序。对于这个例子,我只是尽量保持简单。
  • 使用 Promise 链接?
  • 使用 $q 链接这个服务和回调。这对你来说会容易得多。你可以在 promise 解决时传递数据。你也可以拒绝(作为错误)。

标签: javascript angularjs node.js csv callback


【解决方案1】:

将加载和解析例程分开是个好主意。但是,使用 Promise 代替回调更方便。这就是这种情况下服务的样子:

angular.module('piApp').service("csvService", function($q) {

    // public methods
    function getCsvAsJSON() {
        var deferred = $q.defer();
        var fs = require("fs");
        var Converter = require("csvtojson").Converter;
        var fileStream = fs.createReadStream("Contents/Product Groups/orderTest2.csv");
        var converter = new Converter({constructResult: true});
        converter.on("end_parsed", function(jsonObj) {
            deferred.resolve(jsonObj);
        });
        fileStream.pipe(converter);
        return deferred.promise;
    }

    return {
        getCsvAsJSON: getCsvAsJSON
    }
});

angular.module('piApp').service("dataRetrievalService", ['csvService', function(csvService) {

    function getContents() {
        return csvService.getCsvAsJSON();
    }

    return {
        getContents: getContents
    }
}]);

angular.module('piApp').controller('homeController', ['$scope', 'dataRetrievalService', function ($scope, dataRetrievalService) {

    dataRetrievalService.getContents().then(function(contents) {
        $scope.result = contents;
    });

}]);

【讨论】:

  • 非常感谢您与我们联系。我尝试了您建议的代码并在dataRetrievalService.getContents.then(function(contents) { 线上获得了TypeError: undefined is not a function,特别是在.then。知道为什么会这样吗?我不需要下载另一个脚本就能正确注入 $q 吗?我将检查我的代码并查看 $q 和承诺。如果您知道是什么原因,请告诉我。非常感谢您的帮助。我过去没有使用过 $q 或 promises
  • @dsfq 我发现了我的问题。该行应为dataRetrievalService.getContents().then(function(contents)。你的 sn-p 缺少这些括号,但一旦我添加它们就可以完美地工作。非常感谢!
  • 哎呀,你是对的,这当然应该是一个返回承诺的方法调用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-23
  • 2017-05-06
  • 1970-01-01
相关资源
最近更新 更多