3

オブザーバブルと計算されたオブザーバブルのグリッドがあります。最初の行には、以下のすべての行の値に対する乗数として使用されるパーセンテージが含まれています。ユーザーはパーセンテージ レート値を編集でき、Knockout はすべてのカスケード更新を処理します。また、グリッド内の各パーセンテージ レートに適用される新しいパーセンテージをユーザーが入力できる別のテキスト ボックスも必要です。

初期バインディングは正常に機能し、1 パーセント レートの更新も正常に機能します。

ユーザーがテキスト ボックスに値を入力すると、javascript の警告が発生し、一致するように各パーセンテージ レートを更新するビュー モデルをループします。グリッド列は実際には月ごとの値であるため、パーセンテージを更新するループは 12 回しか実行されません。

スロットルエクステンダーを試しましたが、問題は解決しませんでした。何か案は?

更新:役立つかどうかはわかりませんが、いくつかのコードを追加しました

$("#NewRate").change(function (e) {
    var newRate = parseFloat($(this).val());
    for (var i = 0; i < 12; i++) {
        viewModel.resourceCategory.monthAmounts[i].amount(newRate);
    }
});

function ConvertToDate(jsonDateString) {
    var re = /-?\d+/;
    var m = re.exec(jsonDateString);
    return new Date(parseInt(m[0]));
}

function MonthAmount(amount, dateKey) {
    var self = this;
    self.amount = ko.observable(amount).extend({ throttle: 1 }); //using the throttle to avoid "long running script" warning in IE
    self.dateKey = ConvertToDate(dateKey);
    self.monthIndex = self.dateKey.getMonth();
}

function ResourceCategory(name, monthAmounts) {
    var self = this;
    self.name = name;

    self.monthAmounts = ko.utils.arrayMap(monthAmounts, function (monthAmount) {
        return new MonthAmount(monthAmount.Amount, monthAmount.DateKey);
    });

    self.totalAmount = ko.computed(function () {
        var sum = 0;
        for (var i = 0; i < self.monthAmounts.length; i++) {
            sum += parseFloat(self.monthAmounts[i].amount());
        }
        return sum.toFixed(2);
    }).extend({ throttle: 1 }); //using the throttle to avoid "long running script" warning in IE

    self.averageAmount = ko.computed(function () {
        return (self.totalAmount() / self.monthAmounts.length).toFixed(2);
    }).extend({ throttle: 1 }); //using the throttle to avoid "long running script" warning in IE

}
function ResourceCategoriesMonthTotal(monthIndex, resourceCategories) {
    var self = this;
    self.monthIndex = monthIndex;
    self.dateKey = new Date(new Date().getFullYear(), monthIndex, 1);
    self.amount = ko.computed(function () {
        var val = 0;
        for (var i = 0; i < resourceCategories.length; i++) {
            val += parseFloat(resourceCategories[i].monthAmounts[self.monthIndex].amount());
        }
        return (val).toFixed(2);
    }).extend({ throttle: 1 }); //using the throttle to avoid "long running script" warning in IE
}

self.resourceCategoriesMonthTotals = new Array();
for (var monthIndex = 0; monthIndex < 12; monthIndex++) {
    self.resourceCategoriesMonthTotals.push(new ResourceCategoriesMonthTotal(monthIndex, self.resourceCategories));
}

self.resourceCategoriesTotal = ko.computed(function () {
    var val = 0;
    for (var i = 0; i < self.resourceCategoriesMonthTotals.length; i++) {
        val += parseFloat(self.resourceCategoriesMonthTotals[i].amount());
    }
    return (val / self.resourceCategoriesMonthTotals.length).toFixed(2);
}).extend({ throttle: 1 }); //using the throttle to avoid "long running script" warning in IE
4

2 に答える 2

2

わかりました、これは悪臭を放ちますが、問題は私が自分のページにこれを持っていたことだと思います:

<div data-bind="text: ko.toJSON($root)"></div>

それを削除した後、「スクリプトの実行が遅い」という警告は表示されませんでした。

于 2012-08-13T16:28:02.983 に答える
2

問題はあなたが

一致するように各パーセンテージを更新するビューモデルをループします

その場合、IE の 1 つの答えは、timeout(0) 呼び出しを使用してブラウザーに譲ることです。タイムアウト後に JS が再開したら、ループの次の反復を実行してから、別のタイムアウトを実行します。

これを行った後、それが IE ブラウザであることを嗅ぎつけた場合にのみ、タイムアウトを行います。それ以外の場合は、必要ありません。

于 2012-04-25T14:06:55.997 に答える