提高敲除自定义绑定的效率(经常开火)

improve efficiency on knockout custom binding (firing too often)

本文关键字:常开火 开火 效率 高敲 自定义 绑定      更新时间:2023-09-26

Attached是一些按钮的自定义绑定处理程序的片段,这些按钮被设计为充当单选组。

我遇到的问题是,当我点击一个按钮时,它会触发6次更新。

我想我需要添加油门或以不同的方式绑定,但我是淘汰赛的新手,所以任何帮助都将不胜感激。

或者,当它触发6次相同的更新时,它实际上并没有影响淘汰赛的表现吗?

只要一个指针指向正确的方向就可以了!

ko.bindingHandlers.buttonGroupChecked = {
    init: function (element, valueAccessor, allBindingsAccessor,
    viewModel, bindingContext) {
        if (typeof globalLog !== 'undefined' && globalLog === true){
            console.log("buttonGroupInit");
        }
        var value = valueAccessor();
        var newValueAccessor = function () {
            return {
                click: function () {
                    value($(element).data('value'));
                }
            }
        };
        ko.bindingHandlers.event.init(element, newValueAccessor,
        allBindingsAccessor, viewModel, bindingContext);
    },
    update: function (element, valueAccessor, allBindingsAccessor,
    viewModel, bindingContext) {          
        if ($(element).data('value') == ko.unwrap(valueAccessor())) {
           //$(element).closest('.btn').button('toggle');
           $(element).siblings().removeClass('btn-success').addClass('btn-info');
           $(element).removeClass('btn-info').addClass('btn-success');
        }
        if (typeof globalLog !== 'undefined' && globalLog === true){
            console.log("buttonGroupUpdate" + ko.unwrap(valueAccessor()));
        }
        
        
    }
}
var ViewModel = function () {
    this.optionsValue = ko.observable(2);
};
globalLog = true;
var vm = new ViewModel();
ko.applyBindings(vm);
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div class="btn-group btn-group-justified">
            
            <a href="javascript:void(0)" class="btn btn-lg btn-info" data-value="1" data-bind="buttonGroupChecked: optionsValue">1</a>
            <a href="javascript:void(0)" class="btn btn-lg btn-info" data-value="2" data-bind="buttonGroupChecked: optionsValue">2</a>
            <a href="javascript:void(0)" class="btn btn-lg btn-info" data-value="3" data-bind="buttonGroupChecked: optionsValue">3</a>
            <a href="javascript:void(0)" class="btn btn-lg btn-info" data-value="4" data-bind="buttonGroupChecked: optionsValue">4</a>
            <a href="javascript:void(0)" class="btn btn-lg btn-info" data-value="5" data-bind="buttonGroupChecked: optionsValue">5</a>
            <a href="javascript:void(0)" class="btn btn-lg btn-info" data-value="5+" data-bind="buttonGroupChecked: optionsValue">5+</a>
        </div>
        <span data-bind="text: optionsValue"></span>

我知道你自己已经解决了这个问题,但我只是想提一下,你不需要自定义绑定来实现这一点。下面是一个例子。。。

var ViewModel = function () {
    this.group1 = ['1','2','3','4','5','5+'];
    this.optionsValue = ko.observable('2');
};
globalLog = true;
var vm = new ViewModel();
ko.applyBindings(vm);
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div class="btn-group btn-group-justified" data-bind="foreach:group1">
            
            <a href="javascript:void(0)" class="btn btn-lg" data-bind="css: { 'btn-success': $parent.optionsValue() == $data, 'btn-info': $parent.optionsValue() != $data}, click: $parent.optionsValue, text: $data"></a>
            
        </div>
        <span data-bind="text: optionsValue"></span>

如果有人无意中发现了这一点,这就是我最终的做法,考虑到Dean所说的,它仍然需要一些改进,但应该为某人提供一个良好的起点。

如果可以的话,我只想从DOM中去掉$parent、$data等(我记得在某个地方看到过这样做的方法),但总的来说,这是一个不错的第一次尝试。

//used to abstract out the jQuery dependancies - just in case at some point in the future jQUery is replaced with another library.
function activeClassSingle(element, standardClass, activeClass){
    $(element).siblings().removeClass(activeClass).addClass(standardClass);
    $(element).removeClass(standardClass).addClass(activeClass);
}

ko.bindingHandlers.buttonGroupChecked = {
    init: function (element, valueAccessor, allBindingsAccessor,
    viewModel, bindingContext) {
        var value = valueAccessor();
        var newValueAccessor = function () {
            return {
                click: function () {
                    value(allBindingsAccessor.get('val'));
                }
            }
        };
        ko.bindingHandlers.event.init(element, newValueAccessor,
        allBindingsAccessor, viewModel, bindingContext);
    },
    update: function (element, valueAccessor, allBindingsAccessor,
    viewModel, bindingContext) {          
        if (allBindingsAccessor.get("val") == ko.unwrap(valueAccessor())) {
           activeClassSingle(element, "btn-info", "btn-success");
        }        
    }
}
 var adults = [
    {val: 1, text: "1"},
    {val: 2, text: "2"},
    {val: 3, text: "3"},
    {val: 4, text: "4"},
    {val: 5, text: "5"},
    {val: 6, text: "5+"}
    ];
var ViewModel = function () {
    this.adultsNo = ko.observable(2);
};
var vm = new ViewModel();
ko.applyBindings(vm);
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div class="btn-group btn-group-justified" data-bind="foreach: adults">
            <div class="btn btn-lg btn-info" data-bind="buttonGroupChecked: $parent.adultsNo, val: $data.val, text: $data.text"></div>
        </div>
        <span data-bind="text: adultsNo"></span>