0

Kendo UI スライダーのサイズを動的に変更するクリーンな方法を探していました。Knockout-Kendo と Paul Irish のスマートなサイズ変更プラグインにより、個々のスライダーに対して合理的に実行可能なソリューションにたどり着くことができました。

<div class="sliderWrapper">
    <input class="slider col" data-bind="kendoSlider: { value: currValue, enabled: enabled, min: 0, max: 100, slide: sliderOnSlide, tickPlacement: 'none', smallStep: 1, showButtons: false, tooltip: { 'enabled': false } }, sliderTip: {}" />
</div>

var ViewModel = function (initValue) {
    this.currValue = ko.observable(initValue);
    this.enabled = ko.observable(true);
};

ko.bindingHandlers.sliderTip = {
    init: function(element, valueAccessor) {
        var dragger = $(element).closest('.k-slider').find('.k-draghandle');
        dragger.empty().html('<span class="sliderTip">0%</span>');
    } 
};

ko.applyBindings(new ViewModel(0));

$(window).smartresize(function() {
    $('.sliderBox').each(function() {
        var value = $(this).val();
        $(this).prev().empty().append('<input class="slider col" data-bind="kendoSlider: { value: currValue, enabled: enabled, min: 0, max: 100, slide: sliderOnSlide, tickPlacement: \'none\', smallStep: 1, showButtons: false, tooltip: { \'enabled\': false } }, sliderTip: {}" />');
         ko.applyBindings(new ViewModel(value));
          $(this).prev().find('.sliderTip').text(value + '%');
    });
});

この Fiddle で結果ペインの境界線をドラッグすると、結果を確認できます: http://jsfiddle.net/MontiDesign/DuZK3/24/

満足していますが、複数のスライダーを動的に追加できるノックアウト シナリオを使用してきました ( http://jsfiddle.net/MontiDesign/DuZK3/37/を参照)。ただし、上記の解決策はすべてのスライダーを消去するだけです。カスタム バインディング ハンドラーを使用してバリエーションを試してみましたが、うまくいきませんでした。これがひどい場合はご容赦ください。

ko.bindingHandlers.resizeSlider = {
    init: function(element, valueAccessor, allBindings) {
        var slider = $(element).data('kendoSlider');
        if (slider) {
            $(window).smartresize(function() {
                $(slider).closest('.sliderWrapper').next().each(function() {
                    var value = $(this).val();
                    $(this).prev().empty().append('<input class="slider col" data-bind="kendoSlider: { value: currValue, enabled: enabled, min: 0, max: 100, slide: sliderOnSlide, tickPlacement: \'none\', smallStep: 1, showButtons: false, tooltip: { \'enabled\': false } }, sliderTip: {}" />');
                    ko.applyBindings(new CreateSlider(value));
                    $(this).prev().find('.sliderTip').text(value + '%');
                });
            });
        }
    }
} 

動的に作成されたスライダーの配列を繰り返し処理し、それぞれにサイズ変更機能を適用する必要があると思いますが、Knockout でこれを実現する方法がわかりません。

あなたが提供できる助けを前もって感謝します!

4

1 に答える 1

0

Knockout.js で複数のバインディングを使用せずにこれを行う方法を見つけることができませんでした。これは非常に悪い考えであることがわかりました。

だから剣道のスライダーはやめた。jQuery UI のレンジ スライダーは、ドラッグ ハンドルの位置をハード ピクセルではなくパーセンテージに基づいているため、箱から出してすぐに流動的で、問題なくサイズを変更できます。また、ノックアウトとの相性も抜群です。

私はこのフィドルを見つけ、それを自分のニーズに合わせました:

<button data-bind="click: $root.addThis">Add a Slider</button>

<div id="wrapper" data-bind="foreach: sliders">
    <div class="sliderContainer">
        <div class="checkbox">
            <input type="checkbox" class="checkbox" data-bind="checked: enabled" /> <span class="sansSerif">Charity Name</span>
        </div>
        <div class="slider col" data-bind="slider: currValue, sliderOptions: { min: 0, max: 100, range: 'min', value: 0 }"></div>
        <input class="sliderBox col sansSerif" type="text" data-bind="value: currValue, enabled: enabled, valueUpdate: 'afterkeydown'" />
    </div>
</div>

$(function () {

    function SliderViewModel() {
        var self = this;

        self.sliders = ko.observableArray();
        self.addThis = function() {
            var s = self.sliders;
            s.push(new CreateSlider());
        }
    };

    ko.bindingHandlers.slider = {
        init: function(element, valueAccessor, allBindingsAccessor) {
            var options = allBindingsAccessor().sliderOptions || {};
            $(element).slider(options);
            $('.ui-slider-handle', element).append('<span data-bind="text: currValue">0</span>%');
            ko.utils.registerEventHandler(element, 'slidechange', function(event, ui) {
                var observable = valueAccessor();
                observable(ui.value);
            });
            ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
                $(element).slider("destroy");
            });
            ko.utils.registerEventHandler(element, 'slide', function (event, ui) {
                var observable = valueAccessor();
                observable(ui.value);
            });
        },
        update: function (element, valueAccessor) {
            var value = ko.utils.unwrapObservable(valueAccessor());
            if (isNaN(value)) value = 0;
            $(element).slider('value', value);
        }   
    };

    ko.applyBindings(new SliderViewModel());

    $(document).on('mouseup touchend', function () {
        if ($('.ui-slider-handle').hasClass('ui-state-focus')) {
            $('.ui-slider-handle.ui-state-focus').removeClass('ui-state-focus');
        }
    });

});

function CreateSlider() {
    var self = this;
    self.currValue = ko.observable(0);
    self.enabled = ko.observable(true);
}

完全な例はhttp://jsfiddle.net/MontiDesign/Sb4qG/4/にあります。

于 2013-05-20T19:55:58.043 に答える