【问题标题】:AngularJS use factory to calculate changes to objectAngularJS 使用工厂计算对象的变化
【发布时间】:2015-02-23 17:33:40
【问题描述】:

我想制作一个简单的工资计算器,以便您拥有员工列表及其当前费率和小时数,您可以操纵工资率和小时数来计算出哪些员工的成本最高。

我有以下内容,包含在此 codepen 中。

我试图将我的所有逻辑都保留在工厂中,但是尽管我知道员工模型正在更新,但我无法通过此方法更新薪酬模型。

<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>
<script>
var app = angular.module('app', []);
app.factory('staffFactory', function ($http, $compile, $rootScope, $controller) {
    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"}
    ];

    var unique = {},
        distinct = [];
    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));
    }

    var pay = [];
    for (var p in unique) {
        pay.push([p, unique[p]]);
        pay.sort(function (a, b) {
            return (b[1].pay - a[1].pay);
        });
    }

    var staffService = {};
    staffService.allStaff = function () {
        return staff;
    };

    staffService.CalcPay = function () {
        return pay;
    };

    return staffService;
});

app.controller('MainCtrl', ['$scope', 'staffFactory', function ($scope, staffFactory) {
    $scope.staff = staffFactory.allStaff();
    $scope.CalcPay = staffFactory.CalcPay();
    $scope.keyPress = function(keyCode){
        console.log($scope.staff);
        $scope.CalcPay = staffFactory.CalcPay();
    };    
}]);
</script>

当我将我的 CalcPay 放入控制器(见下文)或此 codepen 时,我可以正常工作。

我读到的所有内容似乎都表明这不是最佳实践并且会减慢应用程序的速度,因此我正在寻找一种方法来完成此操作而不依赖控制器中的功能?

如何实现?

app.controller('MainCtrl', ['$scope', 'staffFactory', function ($scope, staffFactory) {
    $scope.staff = staffFactory.allStaff();
  function CalcPay () {
      var unique = {},
        distinct = [];
    for (var i in $scope.staff) {
        if (typeof (unique[$scope.staff[i].id]) == "undefined")  {
            distinct.push($scope.staff[i].id);
        }
        unique[$scope.staff[i].id] = unique[$scope.staff[i].id] || {pay:0};
        unique[$scope.staff[i].id].name = $scope.staff[i].name;
        unique[$scope.staff[i].id].pay += (parseInt($scope.staff[i].rate, 10) * parseInt($scope.staff[i].hours, 10));
    }

    var pay = [];
    for (var p in unique) {
        pay.push([p, unique[p]]);
        pay.sort(function (a, b) {
            return (b[1].pay - a[1].pay);
        });
    }
  return pay;
  };
    $scope.CalcPay = CalcPay();
    $scope.keyPress = function(keyCode){
        $scope.CalcPay = CalcPay();
    };    
}]);

【问题讨论】:

  • 是的,将业务类型逻辑保留在控制器中是不正确的做法。我不确定,您是否尝试使用工厂方法方法来实现您的结果?并使用第二个代码 sn-p(即控制器内部的逻辑),您将获得所需的结果。对吗?
  • @Vaibhav 是的,我在这里得到了想要的结果(代码的第二位)但是我想改进我的代码,这样我就不会在更大的项目中遇到性能问题。
  • 如果你把你的逻辑保存在工厂里,那么它会被创建为单例实例,所以同一个实例可以在其他控制器中使用,它使编写测试用例变得容易。

标签: javascript angularjs html angularjs-scope angularjs-ng-repeat


【解决方案1】:

问题是当你调用工厂的 CalcPay 方法时,该方法只是返回一个值 pay 。你没有像在另一个代码 sn-p 中那样计算任何东西,你在控制器中计算所有东西。因此,不要只返回支付,而是将所有计算逻辑保留在 CalcPay 中,或者将所有逻辑保留在其他函数中并从 CalcPay 中调用。

var app = angular.module('app', []);
app.factory('staffFactory', function ($http, $compile, $rootScope, $controller) {
    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);
        });
    }
    }
    var staffService = {};
    staffService.allStaff = function () {
        return staff;
    };

    staffService.CalcPay = function () {
        return calcPayInner();
    };

    return staffService;
});

【讨论】:

  • 感谢您提供的信息,这也有助于我的理解!为了让您的 calcPayInner 函数正常工作,我还必须在结束时返回 pay。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-24
相关资源
最近更新 更多