0

提供された JSFiddle の「クリック」イベントのパフォーマンスに関する提案をいただければ幸いです。

複数のオブザーバブルを一度に変更する際のパフォーマンスを向上させることが目的です。

更新通知をバッチで一時停止および再開する方法に関するドキュメントは見つかりませんでした。

http://jsfiddle.net/g9jpxcm2/

$("#all").click(function(){
    var tasks = ko.dataFor($("#tasks")[0]).tasks(),
        checked = this.checked;

    //TODO: performance? Batch changes?
    for(var i = 0, l = tasks.length; i<l; i++){
         tasks[i].done( !!checked );
    }
});
4

2 に答える 2

2

通常、機能する洗練されたソリューションに焦点を当て、パフォーマンスの問題がある場合にのみ最適化するか、少なくとも特定のコードがボトルネックになることが合理的に予想される場合にのみ最適化することをお勧めします。

その精神で、私はすべてのチェックボックスをもう少し応答性の高いものにするソリューションをコーディングしました:

  1. すべてのタスクボックスがチェックされている場合、すべてがチェックされます
  2. すべてがチェックされ、タスクボックスがチェックされていない場合、すべてがチェックされません
  3. すべてをチェックすると、すべてのタスク ボックスがチェックされます
  4. すべてをオフにすると、すべてのタスク ボックスがオフになります

クリック イベントの処理や jQuery の使用はありません。これは値が変化するたびにタスク アイテムを実行しますが、100 個のタスク ボックスを使用しても、顕著なパフォーマンスの問題は発生しないと思います。

var viewModel = ko.mapping.fromJS({
tasks: [{
    name: "Task 1",
    done: false    
},{
    name: "Task 2",
    done: true    
},{
    name: "Task 3",
    done: false    
}]
});

viewModel.allChecked = ko.computed({
read: function () {
    var tasks = viewModel.tasks();
    for (var i=0; i<tasks.length; ++i) {
        if (!tasks[i].done()) {
            console.debug("Nope");
            return false;
        }
    }
    return true;
},
write: function (newValue) {
    var tasks = viewModel.tasks();
    for (var i=0; i<tasks.length; ++i) {
        tasks[i].done(newValue);
    }
}
});

ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://cdn.rawgit.com/SteveSanderson/knockout.mapping/master/build/output/knockout.mapping-latest.js"></script>
<label>All</label>
<input id="all" type="checkbox" data-bind="checked:allChecked" />
<br><br><br>
<div id="tasks" data-bind="foreach: tasks">
<label data-bind="text: name"></label>
<input type="checkbox" data-bind="checked: done" />    
</div>

于 2015-07-20T15:50:02.197 に答える
0

どのタスクがチェックされているかを直接示すのではなく、チェックされたタスクのコレクションを追跡するようにモデルを変更できます。単一のオブザーバブルのみが更新されるため、実装がより簡単かつ高速になるはずです。(観察可能な)配列を作成し、checkedバインディングを配列にバインドするだけです。valueがバインドされていることも確認してください。

<div id="tasks" data-bind="foreach: tasks">
    <label data-bind="text: name"></label>
    <input type="checkbox" data-bind="checked: $parent.checkedTasks, value: $data" />
</div>
var data = {
    tasks: [{
        name: "Task 1"
    },{
        name: "Task 2"
    },{
        name: "Task 3"
    }]
};

ko.applyBindings( ko.mapping.fromJS(data, {}, {
    checkedTasks: ko.observableArray([])
}), $("#tasks")[0]);

$("#all").click(function(){
    var model = ko.dataFor($("#tasks")[0]),
        checked = this.checked;

    if (checked) {
        model.checkedTasks(model.tasks().slice(0));
    } else {
        model.checkedTasks([]);
    }
});

フィドル

于 2015-07-20T17:26:23.323 に答える