【问题标题】:How to use data from API in factory AngularJS如何在工厂AngularJS中使用来自API的数据
【发布时间】:2023-03-17 01:19:01
【问题描述】:

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

'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);
    });

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

我也尝试在 .success 之后将函数包装在 .finally 中,但随后我的函数变得未定义。

如何在工厂的函数中使用 API 数据,以便让我的页面像原来使用硬编码数组一样工作?

【问题讨论】:

    标签: javascript html angularjs angularjs-service


    【解决方案1】:

    其他人提到的问题是您试图在数据可用之前获取数据。如果您想保持单一数据源,则该问题的解决方案是在您的工厂内使用 Promise。

    以下代码使用q,因此您必须将其注入您的工厂。

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

    allStaff 实施

    /* 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

    【讨论】:

    • 谢谢,不仅是答案,还有代码中的伟大 cmets。在使用 Promise 时,这对于其他人来说也是一个很好的工作示例。
    【解决方案2】:

    我就是这样做的:

    $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... */
    });
    

    【讨论】:

    • 谢谢。我读到的每一件事都说要让所有业务逻辑远离控制器,我正在工厂寻找可行的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-09
    • 2023-03-26
    相关资源
    最近更新 更多