Knockout自定义绑定导致双重事件?

时间:2014-02-27 14:37:06

标签: jquery knockout.js

我刚刚创建了一个自定义的淘汰赛绑定,似乎表现得有些奇怪,我想知道是否有人可以提供帮助。我把JSFiddle放在一起来说明:

JSFiddle

我注意到的是,我似乎每次都要点击拨动开关两次才能切换。

enter image description here

我已将其分离到自定义绑定中的以下行(JSFiddle中的第27行):

valueAccessor()(active);

如果你对这一行进行评论,那么你突然需要点击一下滑块来改变,显然在这种情况下绑定会中断。​​

任何人都可以解释原因可能是什么,或者我怎么能解决它?

2 个答案:

答案 0 :(得分:1)

最简单的方法是从切换控件中分离实际的点击功能,并让Knockout处理它。这样,可观察值将始终与切换控制状态匹配。以下是使用此方法的更新JavaScript。我添加了一个超时,以显示当值在附加到它的click事件之外发生变化时,observable将更新切换控件的状态。

$('.toggle').each(function () {

    var self = $(this);
    var onText = self.attr("data-on") || "ON";
    var offText = self.attr("data-off") || "OFF";

    // Go through each item individually so we can get the data-id out
 var toggle = $(this).toggles({ text: { on: onText, off: offText }, drag: false, click: false });
});
// Define the knockout custom toggle binding see
// http://knockoutjs.com/documentation/custom-bindings.html
ko.bindingHandlers.toggle = {
    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
        // This will be called when the binding is first applied to an element
        // Set up any initial state, event handlers, etc. here

        // Configure an event to update the observable when the slider is clicked
        ko.utils.registerEventHandler(element, "click", function () {
            var observable = valueAccessor();
            observable( ! observable() );
        });
    },
    update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
        // This will be called once when the binding is first applied to an element,
        // and again whenever the associated observable changes value.
        // Update the DOM element based on the supplied values here.
        // Grab the value for the item then update the toggle
        var value = ko.unwrap(valueAccessor());
        if ( true === value ) {
            $(element).trigger("toggleOn");
        }  else {
            $(element).trigger("toggleOff");
        }   
    }
};

var viewModel = {};
var settings = {};
settings.test = { value: "test", override: true };
viewModel.settings = ko.mapping.fromJS(settings);

ko.applyBindings(viewModel);

setTimeout( function() {
    viewModel.settings.test.override( false );
}, 5000 );

这是一个更新的,有效的小提琴:http://jsfiddle.net/6L5Tq/1/

答案 1 :(得分:0)

如果您发表评论

,一切都会正常
 update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
    console.log("update");
    var value = ko.unwrap(valueAccessor());
    /*if (value) 
        $(element).trigger("toggleOn");
    else
        $(element).trigger("toggleOff");*/
}

<强> JSFIDDLE

它将是一个侧面绑定,以防止您在触发之前检查更新中的可观察值不等于toggle-plugin状态。但jquery-toggles的功能非常差,我无法确定国家财产。