2

由于发票行计算的复杂性,我需要创建发票行将是独立控制器的发票。
我的问题是:如何定义 InvoiceLine 控制器数组并使用 ng-repeat 绑定它们?

我是 Angular 的新手,在淘汰赛中我是这样做的:http: //knockoutjs.com/examples/cartEditor.html

    <script type="text/javascript">
    var invoiceTest = angular.module("InvoiceTest", []);

    invoiceTest.controller(
        "InvoiceHead",
        function ($scope) {
            // how to define ? $scope.InvoiceLine = [array of controllers]
            $scope.VAT = 0.17;
            $scope.TotalNoVat = ???; // Neet To Calc the Sum of $scope.InvoiceLine.TotalCost
            $scope.TotalInvluceVAT = function() {
                return ($scope.TotalNoVat * (1+ $scope.VAT)).toFixed(2);
            };
        }
        );

    invoiceTest.controller("InvoiceLine",
        function ($scope) {
            $scope.Description = "";
            $scope.Quantity = 1;
            $scope.Cost = 0;
            $scope.TotalCost = function() {
                return ($scope.Quantity * $scope.Cost).toFixed(2);
            };

            //more complex  calculation and ajax ...
        }
    );

</script>
4

1 回答 1

2

如果 Invoice Line Item 有一个 UI 组件(我想它确实有),这听起来像是一个使用AngularJS 指令的好地方

该指令将包含显示发票行项目的必要逻辑,并且它可以包含(通过其控制器)计算显示行项目的值所需的逻辑。

如果您想要更多地分离您的关注点,您还可以创建一个AngularJS 服务,该服务包含计算订单项值的逻辑,并将服务注入指令的控制器。 这样做的好处是允许您对计算逻辑进行单元测试,而无需涉及显示逻辑。

这是如上所述使用的服务和指令的真实基本示例(MainInvoiceController用于保存lineItems):

invoiceTest.controller("MainInvoiceController", function($scope){

    // lineItem directive will update Quantity & Cost as user changes
    // changes input values, and recalculate TotalCost any time either
    // Quantity or Cost changes.
    $scope.lineItems = [
        {
            Description : "Item 1",
            Quantity: 2,
            Cost: 2.00,
            TotalCost: 4.00
        },
        {
            Description : "Item 2",
            Quantity: 10,
            Cost: 4.00,
            TotalCost: 40.00
        },
    ]
});

invoiceTest.service("InvoiceCalculationsService", function(){
    // Calculates the total cost of the line item, and
    // updates the TotalCost property of the line item
    this.updateTotalCost = function(lineItemData)
    {
        lineItemData.TotalCost = lineItemData.Quantity * lineItemData.Cost;
    }
});

InvoiceTest.directive("lineItemDisplay", function(InvoiceCalculationsService){
    return {
        restrict:"AE",
        scope:{
            // lineItemData is expected to contain the properties:
            // Description
            // Quantity
            // Cost
            // TotalCost
            lineItem:"="
        },
        controller: function($scope, $element, $attrs){
            this.recalculateTotal = function(){
                InvoiceCalculationsService.updateTotalCost($scope.lineItem);
            }
        },
        template:   'Description: <input data-ng-model="lineItem.Description" />'
                    'Quantity: <input data-ng-model="lineItem.Quantity" data-ng-change="recalculateTotal()" />' +
                    'Cost: <input data-ng-model="lineItem.Cost" data-ng-change="recalculateTotal()" />' + 
                    'Total: <span>{{lineItem.TotalCost}}</span>'
    }
});

这是正在使用的指令,带有`ng-repeat':

<div data-ng-controller="MainInvoiceController">
<ul>
    <li data-ng-repeat="lineItem in lineItems">
        <line-item-display data-line-item="lineItem"></line-item-display>
    </li>
</ul>
</div>
于 2013-10-06T00:22:15.103 回答