0

ブラウザーでノックアウト .js と MVVM パターンを多用する ASP.NET MVC 4 アプリを強化しようとしています。私はノックアウトを手に入れていて、とても気に入っていますが、予期しないバグを引き起こすことができました.

テーブルがあり、ノックアウト ビューモデルをループして行を作成するデータ バインド属性で foreach ルックを使用しています。

ビューモデルでは、テーブルの数値列を合計する新しいフッター行をサポートするために、さらにいくつかの属性を追加しました。

残念ながら、ビューモデルに追加した属性により、コントローラーにポストバックすると行が削除されます。これらの合計を追加するために間違ったノックアウト構造を使用していると思われます...

...これはビューモデル内にあります...

self.BudgetTotal = ko.computed(function () {
    var total = 0;
    //The problem is this loop! It's messing with the Phases observable array and it's all magic behind the scenes and I can't see what's going wrong
    for (i = 0; i < self.Phases().length; i++)
        total = parseFloat(total) + parseFloat(self.Phases()[i].Total());
    return format_number(total, 2);
});

これはテーブルです:

<table class="table table-bordered table-compact">
                <thead>
                    <tr>
                        <th></th>
                        <th>Phase</th>
                        <th>Name</th>
                        <th>Phase Manager</th>
                        <th>Labor</th>
                        <th>Expense</th>
                        <th>Subs</th>
                        <th>Total</th>
                    </tr>
                </thead>
                <tbody data-bind="template: {foreach: Phases.sort(function (l, r) { return l.Code() > r.Code() ? 1 : -1 }) }">
                    <tr>
                        <td><input type="checkbox" data-bind="checked: IsSelected, click:SelectionChanged"/></td>
                        <td class="phasecode" data-bind="text: Code"></td>
                        <td><input type="text" data-bind="value: Name, visible: IsAdditional" class="input-small phaseName" maxlength = "35"/><span data-bind="text: Name, visible: !IsAdditional()"></span></td>
                        <td><input type="hidden" id="CompanyCode" data-bind="value: Company().Code" /><input type="text" class="PhaseManagerTypeahead phaseManager" data-bind="value: PhaseManager().CodeName, enable: IsSelected" autocomplete="off"/></td>
                        <td>
                            <nobr><input class="span1" id="inputIcon" type="text" data-bind="value: Labor, enable: IsSelected" style="text-align:right" onblur="checkDecimal(this)" maxlength = "20"/></nobr>
                        </td>
                        <td>
                            <nobr><input class="span1" id="inputIcon" type="text" data-bind="value: Expenses, enable: IsSelected" style="text-align:right" onblur="checkDecimal(this)" maxlength = "20"/></nobr>
                        </td>
                        <td>
                            <nobr><input class="span1" id="inputIcon" type="text" data-bind="value: Subcontractor, enable: IsSelected" style="text-align:right" onblur="checkDecimal(this)" maxlength = "20"/></nobr>
                        </td>
                        <td data-bind="text: Total" style="min-width:80px; text-align:right"></td>
                    </tr>                                            
                </tbody>
                <tfoot class="hideFromPrinter">
                    <tr>
                        <td colspan="8"><a href="javascript:void(0);" data-bind='click: viewModel.addAdditionalPhase'>Add Additional Phase...</a></td>
                    </tr>
                </tfoot>
            </table>

合計を表示するフッター行を削除しましたが、バグとは無関係であることがわかりました。上記のノックアウト コードをコメント アウトすると、バグが消えます。コメントを外すと、バグが返されます。

解決策は、ユーティリティ関数 arrayForEach を使用して監視可能な配列を反復処理することでした。

self.BudgetTotal = ko.computed(function () {
var total = 0;
ko.utils.arrayForEach(self.Phases, function (item) {
    var value = parseFloat(item.Total());
    if(!isNaN(value))
        total += value;
    }
);
return total.toFixed(2);
});
4

2 に答える 2