2015-11-03 143 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