2015-11-03 121 views
1

我正在尝试将自定义绑定和noUiSlider融合在一起。我发现了jQuery-UI滑块和Knockout的类似代码,并将其用作基础。Knockout,noUiSlider,自定义绑定

如果我使用下面的sliderko自定义绑定,noUisliders不会更新observables。我得到了NaN,而且没有输入字段。

如果我直接使用noUiSlider事件下面的滑块自定义绑定,那么一切正常。滑块自定义绑定效果不佳,可能是由于跟踪了noUiSlider更新事件。但是,这是我能弄清楚如何让滑块持续更新输入字段的唯一方法。

我想使用Knockout的registerEventHandler,但我不知道如何让它工作。

// noUiSlider 
 
ko.bindingHandlers.slider = { 
 
    init: function(element, valueAccessor, allBindingsAccessor) { 
 
    var options = allBindingsAccessor().sliderOptions || {}; 
 
    noUiSlider.create(element, options); 
 

 
    // works with with noUiSlider but not with knockout event bindings 
 
    element.noUiSlider.on('set', function(values, handle) { 
 
     var observable = valueAccessor(); 
 
     observable(values[handle]); 
 
    }); 
 

 
    // works with with noUiSlider but not with knockout event bindings 
 
    element.noUiSlider.on('update', function(values, handle) { 
 
     var observable = valueAccessor(); 
 
     observable(values[handle]); 
 
    }); 
 

 
    ko.utils.domNodeDisposal.addDisposeCallback(element, function() { 
 
     element.noUiSlider.destroy(); 
 
    }); 
 
    }, 
 
    update: function(element, valueAccessor) { 
 
    var value = ko.utils.unwrapObservable(valueAccessor()); 
 
    element.noUiSlider.set(value); 
 

 
    } 
 
}; 
 

 
// using knockout event handlers 
 
ko.bindingHandlers.sliderko = { 
 
    init: function(element, valueAccessor, allBindingsAccessor) { 
 
    var options = allBindingsAccessor().sliderOptions || {}; 
 
    noUiSlider.create(element, options); 
 

 
    ko.utils.registerEventHandler(element, 'set', function(values, handle) { 
 
     var observable = valueAccessor(); 
 
     observable(values[handle]); 
 
    }); 
 

 
    ko.utils.registerEventHandler(element, 'update', function(values, handle) { 
 
     var observable = valueAccessor(); 
 
     observable(values[handle]); 
 
    }); 
 

 
    ko.utils.domNodeDisposal.addDisposeCallback(element, function() { 
 
     element.noUiSlider.destroy(); 
 
    }); 
 
    }, 
 
    update: function(element, valueAccessor) { 
 
    var value = ko.utils.unwrapObservable(valueAccessor()); 
 
    element.noUiSlider.set(value); 
 

 
    } 
 
}; 
 

 
// initialization for NoUiSlider - saves from adding stuff into page 
 
var sillysv = { 
 
    start: [10], 
 
    step: 0.01, 
 
    range: { 
 
    'min': 0, 
 
    'max': 100 
 
    } 
 
}; 
 

 
var sillysp = { 
 
    start: [5], 
 
    step: 0.01, 
 
    range: { 
 
    'min': 0, 
 
    'max': 100 
 
    } 
 
}; 
 

 
var ViewModel = function() { 
 
    var self = this; 
 
    self.savings = ko.observable(); 
 
    self.spent = ko.observable(); 
 
    self.net = ko.computed(function() { 
 
    return self.savings() - self.spent(); 
 
    }); 
 
}; 
 

 
ko.applyBindings(new ViewModel());
<link href="https://cdnjs.cloudflare.com/ajax/libs/noUiSlider/8.1.0/nouislider.min.css" rel="stylesheet" /> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/noUiSlider/8.1.0/nouislider.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
 
<h2>Slider Demo</h2> 
 
Savings: 
 
<input data-bind="value: savings" /> 
 
<div style="margin: 10px" data-bind="slider: savings, sliderOptions: sillysv"></div> 
 

 
Spent: 
 
<input data-bind="value: spent" /> 
 
<div style="margin: 10px" data-bind="slider: spent, sliderOptions: sillysp"></div> 
 

 
Net: <span data-bind="text: net"></span>

回答

0

如果你正在使用jQuery有与jQuery或KO registerEventHandler结合事件之间没有什么区别。此功能用于内部使用,并且能够使绑定在不同的浏览器中正常工作。如果jQuery可用,则此函数使用jQuery绑定。

第二个问题,更新可观察的很多次,应该通过调节可观察值的升高来解决。你可以直接在您的视图模型使用rateLimit ko extender

var ViewModel = function() { 
    var self = this; 
    self.savings = ko.observable() 
    .extend({ rateLimit: { method: "notifyWhenChangesStop", timeout: 400 } });; 
    self.spent = ko.observable() 
    .extend({ rateLimit: { method: "notifyWhenChangesStop", timeout: 400 } });; 
    self.net = ko.computed(function() { 
    return self.savings() - self.spent(); 
} 

您还可以修改自定义绑定,如果你想在init延长观测。如果你这样做,你应该检查观测值是否已经被扩展:Check if extension was applied to observable

+0

这是正确的想法,但它打破了绑定的反馈目的。我会在下面发布一些我发现的作品。请注意,我是javascript noob(主要是基础架构和服务器编程)。 –

+0

不,它根本不会影响反馈,如果您选择正确的超时时间:您可以选择一个足够高的时间以避免性能问题,并且足够低以供用户察觉。如果400ms太高,可以将数字降低到100ms,或50ms,甚至20ms。无论您选择哪个号码,条形图都将平稳移动,用户将无法阅读文本中的所有更改,或者以如此高的速率读取任何其他绑定。请在丢弃解决方案之前对其进行测试。不过,我真的很想看到你找到的解决方案。 – JotaBe

相关问题