代码之家  ›  专栏  ›  技术社区  ›  ak85

如何在工厂AngularJS中使用API中的数据

  •  0
  • ak85  · 技术社区  · 10 年前

    我有以下代码,它使用员工数组中的数据来计算员工薪酬。

    'use strict';
    var app = angular.module('app', []);
    app.factory('staffFactory', function ($http) {
        var staff = [
            {"id": "1","name": "Kate","rate": "10", "hours": "10"},
            {"id": "2","name": "John","rate": "20", "hours": "10"},
            {"id": "3","name": "Matt","rate": "15", "hours": "10"}
        ];
    
      function calcPayInner(){
        var unique = {},
            distinct = [],pay = [];
        for (var i in staff) {
            if (typeof (unique[staff[i].id]) == "undefined")  {
                distinct.push(staff[i].id);
            }
            unique[staff[i].id] = unique[staff[i].id] || {pay:0};
            unique[staff[i].id].name = staff[i].name;
            unique[staff[i].id].pay += (parseInt(staff[i].rate, 10) * parseInt(staff[i].hours, 10));
        }
    
            for (var p in unique) {
                pay.push([p, unique[p]]);
                pay.sort(function (a, b) {
                  return (b[1].pay - a[1].pay);
                });
            }
            return pay;
        }
        var staffService = {};
        staffService.allStaff = function () {
            return staff;
        };
    
        staffService.CalcPay = function () {
            return calcPayInner();
        };
    
        return staffService;
    });
    
        app.controller('MainCtrl', ['$scope', 'staffFactory', function ($scope, staffFactory) {
            $scope.staff = staffFactory.allStaff();
            console.log($scope.staff);
            $scope.CalcPay = staffFactory.CalcPay();
            $scope.keyPress = function(keyCode){
                $scope.CalcPay = staffFactory.CalcPay();
            };    
        }]);
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    <div ng-app="app">
            <div ng-controller="MainCtrl">
              <table>
                <tr><td>name</td><td>rate</td><td>hours</td></tr>
                <tr ng-repeat="s in staff">
                    <td>{{s.name}}</td>
                    <td><input ng-keyup="keyPress(s.rate)" ng-model="s.rate"></td>  
                    <td><input ng-keyup="keyPress(s.hours)" ng-model="s.hours"></td>
                </tr>
                </table>
              <table>
                <tr><td>name</td><td>pay</td></tr>
                <tr ng-repeat="b in CalcPay">
                    <td>{{b.1.name}}</td>
                    <td>{{b.1.pay}}</td>
                </tr>
                </table>          
        </div>
    </div>

    这一切都按预期工作,但现在我希望从API调用中获取员工数据,而不是硬编码数据。

    我已经尝试了以下方法。( see plnkr )

        var staff = [];
        var test = $http.get('staff.json')
        .success(function(data) {
            staff = data;
            console.log(staff);
        });
    

    它似乎返回了我在控制台中看到的数据,但我无法让它与现有函数一起工作(返回一个空白数组)。

    我还尝试将函数包装在.finally after.success中,但随后我的函数变得不定义。

    我如何在工厂的函数中使用API数据,以便我的页面能够像最初使用硬编码数组时那样工作?

    2 回复  |  直到 10 年前
        1
  •  2
  •   Ehtesham    10 年前

    其他人提到的问题是,您试图在数据可用之前获取数据。解决这个问题的方法是,如果您想保持数据的单一来源,那么在工厂内使用promise。

    以下代码使用 q 所以你必须在工厂里注射。

    app.factory('staffFactory', function ($http, $q) {}
    

    全体员工实施

    /* Private var to hold the staff */
    var staff = [];
    
    // this method returns a promise
    staffService.allStaff = function () {
        var deferred = $q.defer();
    
        // check if staff is already fetched from server if yes resolve the promise immediately
        if (staff.length > 0) {
            // we have data already. we can avoid going to server
            deferred.resolve(staff);   // staff holds all the data
        } else {
            // data is not available yet. fetch it from server
    
            $http.get('staff.json')
            .success(function(data) {
                // once data is available resolve
                staff = data;
                deferred.resolve(data);
            })
            .error(function (error) {
                deferred.reject(error);
            });
        }
    
        return deferred.promise;
    };
    

    在控制器中。

    staffFactory.allStaff().then(function (staff) {
        $scope.staff = staff;
        console.log($scope.staff);
        $scope.CalcPay = staffFactory.CalcPay();
        $scope.keyPress = function(keyCode) {
            $scope.CalcPay = staffFactory.CalcPay();
        }; 
    });
    

    签出 plunkr

        2
  •  1
  •   Alex Szabo    10 年前

    我是这样做的:

    $scope.documents = [];
    
    $http.post('get_xml.php')
        .then(function (result) {
            $scope.documents = result.data;
            console.log(result.data);
        });
    

    据我所知 .then 是一个异步函数,它将在阵列可用时立即更新。

    因此,在您的情况下,应该是:

    app.factory('staffFactory', function ($http) {
    
        var staff = [];
        var test = $http.get('staff.json').then(function(result) {
            staff = result.data;
            console.log(staff);
        });
    
        /* Rest of your code... */
    });