2015-09-04 52 views
0

我有下面的代碼,它使用員工數組中的數據來計算員工工資。如何在工廠使用API​​數據AngularJS

'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​​數據,以便我的頁面能夠像最初使用硬編碼數組一樣工作?

回答

2

如其他人所說的問題是,你正在試圖獲得的數據是可用之前。如果你想保持數據的單一來源,解決這個問題的方法是在工廠內部使用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

+0

非常感謝,不僅僅是爲了答案,還要感謝代碼中的精彩評論。這對於其他人在使用承諾時也是一個很好的工作示例。 – ak85

1

這是我做的:

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

謝謝。我讀過的每一件東西都說,爲了讓所有的業務邏輯都不用控制器,我正在尋找工廠中的工作解決方案。 – ak85