(AngularJS)计算每个不同百分比的动态小计

时间:2014-05-21 17:52:47

标签: angularjs

我是AngularJS的新手,非常感谢小费。我有一个列数量的表和两列百分比。在这两列中,用户可以输入不同的百分比。

现在我想首先用相同的百分比来总结金额,然后乘以百分比。然后应为每个百分比动态创建小计行。

你能给我一个暗示吗?这是一个小提琴,以证明它:fiddle

HTML

<table ng:controller="SubTotalCtrl">
    <thead>
        <tr>
            <th ng:repeat="(i,th) in head" ng:class="selectedCls(i)" ng:click="changeSorting(i)">{{th}}</th>
        </tr>
    </thead>
    <tbody>
        <tr ng:repeat="row in body.$orderBy(sort.column, sort.descending)">
            <td><input value = {{row.a}}></input></td>
            <td><input value = {{row.b}}></input></td>
            <td><input value = {{row.c}}></input></td>
        </tr>
    </tbody>
    <tfoot>
        <tr>
        <td></td>
        <td><textarea>Label Subtotal Percent 5</textarea></td>      
        <td>= (Sum of all Amounts with 5% *  5 %)</td>
         </tr><tr> 
         <td></td>
        <td><textarea>Label Subtotal Percent 10</textarea></td>      
        <td>= (Sum of all Amounts with 10% *  10 %)</td>
        </tr><tr> 
        <td></td>
        <td><textarea>Label Subtotal Percent 20</textarea></td>      
        <td>= (Sum of all Amounts with 20% * 20%)</td>
         </tr>        
</table>

SCRIPT

function SubTotalCtrl() {
    var scope = this;

    // data
    scope.head = {
        a: "Amount",
        b: "Percent",
        c: "Percent"
    };
    scope.body = [{
        a: "1000",
        b: "5",
        c: "10"
    }, {
        a: "2000",
        b: "0",
        c: "5"
    }, {
        a: "3000",
        b: "10",
        c: "20"
    }];
}

1 个答案:

答案 0 :(得分:4)

您的代码存在相当多的问题(超出了本答案的范围) 最值得注意的是,你使用的是一个(实际上是两个)古代版本的Angular。

关于实际问题(如何生成动态百分比组和每组总数):

<强> 1
您需要一种方法将视图绑定到模型。这意味着,无论何时用户输入新值(例如修改某个百分比值),您都需要在视图中显示每行分配的百分比更新您的模型(您的数据)。 Angular通过双向数据绑定使其变得非常简单:

<input type="text" ng-model="row.a" />
// Now he input will show whatever value is stored in `$scope.row.a`
// and `$scope.row.a` will get automatically updated whenever the user
// enters a different value into the text-field. 

<强> 2
您需要创建百分比组并使用ngRepeat为每个组渲染一行。这需要是动态的,因为组将根据用户的输入而改变 我发现以下格式很好用:

groups = {
    <percentage1>: <sumOfAmounts1>
    <percentage2>: <sumOfAmounts2>
    ...

E.g。

groups = {
    '5': 1200,
    '10': 700,
    ...

然后在你的视图中使用它:

<tr ng-repeat="(perc, sum) in grouppedByPercentage()">
    <td></td>
    <td>Subtotal for {{perc}}%</td>      
    <td>{{sum * perc / 100.0}}</td>
</tr>

第3
最后,您需要在$scope中生成并返回组的方法:

$scope.grouppedByPercentage = function () {
    var groups = {};
    $scope.body.forEach(function (row) {
        ['b', 'c'].forEach(function (key) {
            var perc = row[key];
            if (perc === '0') { return; }   // ignore 0 percentage

            if (!groups[perc]) {
                // The group for this percentage does not exist
                // Let's create it first
                groups[perc] = 0;
            }
            groups[perc] += parseInt(row.a);
            // use `parseFloat()` if you want decimal points
        });
    });
    return groups;
};

另请参阅此 short demo


注意:
有更有效的方法可以做到这一点(例如,生成一次组,然后在重新生成数据之前注意数据的变化),但我选择尽可能简单地保持这一点,考虑到你的新手&#34;角色状态。


<强>更新

原始演示的

This is an extended version ,除了原始(更简单的方法)之外,还有一种更有效(计算)的替代方案,并正确地对百分比进行排序。

解决方案之间的比较:

解决方案1 ​​(使用对象):
+ 可能更容易理解(更直接) - 效率较低(在每个摘要周期生成组(可能有很多) - 将百分比排序为字符串(而非数字),从而导致例如10%之前出现5%

解决方案2 (使用数组):
- 稍微复杂一点(例如,它使用$watch + 更高效(仅在数据实际更改时生成组) + 将百分比排序为数字,因此所有内容都以正确的(算术)顺序显示。