在AngularJS应用中,我如何将一个函数的结果用于另一个函数

In an AngularJS app how can I use the results of one function for another?

本文关键字:函数 一个 另一个 用于 结果 应用 AngularJS      更新时间:2023-09-26

我对AngularJS还是相当陌生的,我被一些我认为过于复杂的东西卡住了。在我的一个控制器中,我有两个函数调用我的数据工厂,但我需要第二个函数使用第一个函数的结果。

当我使用下面的代码片段时,我一直得到未定义的顺序。我不想把第二个函数放在第一个函数的成功部分。我如何将结果传递给第二个调用?

app.controller('joDetailCtrl',
function ($modal, $scope, $http, modalService, dataFactory, $routeParams) {
    dataFactory.getJobOrder($routeParams.joNumber)
        .success(function (order) {
            $scope.status = 'Retrieved job order details';
            $scope.order = order;
        })
        .error(function (error) {
            $scope.status = 'Error retrieving job order details ' + error.message;
        });
    dataFactory.getJobOrderDetails(order[0].customerID, order[0].jobOrderID)
        .success(function (details) {
            $scope.status = 'Retrieved job order line items';
            $scope.details = details;
        })
        .error(function (error) {
            $scope.status = 'Error retrieving line items' + error.message;
        });
});

您得到未定义,因为getJobOrder可能没有完全执行,并且在调用getJobOrderDetails之前分配了范围变量,因为函数是异步的。你可以把承诺链接起来。

你明白了吗?这里的Plunker http://plnkr.co/edit/bzMhsW

angular.module('app', [])
  // Controller
  .controller('Ctrl', function($scope, $q, dataFactory) {
    // Get some order and it's details
    $scope.status = 'Please wait...';
    getOrder({ joNumber: 123 }).then(getDetails);
    // Wrapper for factory 
    function getOrder(job) {
      return dataFactory.getJobOrder(job.joNumber)
        .then(function(order) {
          $scope.status = 'Retrieved job order';
          $scope.order = order;
          return $q.when(order);
        });
    }
    // Other wrapper for factory    
    function getDetails(order) {
      return dataFactory.getJobOrderDetails(order[0].customerID, order[0].jobOrderID)
        .then(function(details) {
          $scope.status = 'Retrieved order line items';
          $scope.details = details;
        });
    }
  })
  // Mock data factory
  .factory('dataFactory', function($q, $timeout)  {
     return {
        getJobOrder: function(joNumber) {
          return $timeout(function() {
            return $q.when([{
              customerID: Math.floor((Math.random() * 10) + 1),
              jobOrderId: joNumber
            }]);          
          }, 1000);
        },  
        getJobOrderDetails: function(customerID, jobOrderID) {
          return $timeout(function() {
            return $q.when({
              details: 'details'
            });
          }, 1000);
        }
      };
  });

<body ng-controller="Ctrl">
  <div>status:{{ status }}</div>
  <div>order:{{ order | json }}</div>
  <div>details:{{ details | json }}</div>
</body>

注意作用域的顺序:

$scope.$watch("order", function(newValueOfOrder){
  //call your other function here if newValueOfOrder is set
});

我没有像在appfactory中那样设置控制器。然而,在我的应用程序中,我使用了控制器中一个函数的结果,并将其传递给同一控制器中的另一个函数。

这个例子使用了d3js中的条形图,所以我删掉了misc。材料,这样就不会拉长答案。只关注$scope。在我的例子中是Bardata。这就是我在你的问题中所述的"传递给另一个函数的结果"。

我刚刚设置了一个全局$作用域。Bardata变量,可以通过任何函数在我的控制器访问。在这种情况下,我正在进行一个异步调用来获取数据,然后将该数据传递给控制我的条形图显示的另一个函数。

所以在下面的例子中,我有我的控制器"ResultsCtrl"和我的两个函数"d3j"(条形图显示)和"getResultsWaiting"(异步调用数据显示到条形图)。在两个函数之间传递的结果称为"bardata"。我将这个"bardata"设置为控制器中的全局作用域。您将看到它被视为"$scope"。没有包含在任何函数中。它在函数之外。

下面是我的代码:
conferenceApp.controllers.controller('ResultsCtrl', function($scope, $log, $routeParams){
    $scope.bardata = $scope.bardata || {};
    $scope.d3j = function () {
        var bardata = $scope.bardata;
        var names = ['Hangout1', 'Hangout2', 'Hangout3'];
        ...etc etc.
        };
    $scope.getResultsWaiting = function () {
    gapi.client.conference.getResultsWaiting({
        webSafeKey: $routeParams.webSafeKey
    }).
        execute(function(resp){
            $scope.$apply(function() {
                if (resp.error){
                    $log.error('There was an Error');
                }
                else {
                    $log.info("Success");
                    $scope.webSafeKey = $routeParams.webSafeKey;
                    $scope.results = []
                    $scope.result=[]
                    angular.forEach(resp.items, function(result){
                        $scope.results.push(result);
                    });
                    $scope.bardata = JSON.parse(resp.items[0]['finalResults']);
                    $scope.d3j();
                    ...etc etc.
                    };

因为我使用了$scope。bardata作为一个全局变量,我可以在一个控制器的函数之间传递它。