0

我正在使用 Knockout 模型,我希望使用 jQuery UI 范围滑块更新此模型中的值。考虑以下示例:

模型:

var ViewModel = function () {
    var self = this;
    self.MinTerm = ko.observable();
    self.MaxTerm = ko.observable();
}

ko.applyBindings(new ViewModel());

现在,一个 jQuery UI 范围滑块应该更新这两个值。这个(非常丑陋的)解决方案接近了,我的 ViewModel 中的值正在更新,但不知何故这并没有反映在绑定到这些值的控件中,例如:

HTML

<div id="sliderTerms"></div>
<span data-bind="text: MinTerm"></span>
<span data-bind="text: MaxTerm"></span>

脚本:

    $("#sliderTerms").slider({
        range: true,
        min: 6,
        max: 120,
        values: [6, 120],
        step: 1,
        slide: function (event, ui) {
            ViewModel.MinTerm = ui.values[0];
            ViewModel.MaxTerm = ui.values[1];
        }
    });

现在,如果我可以绑定到像这样的自定义 bindingHandler 那就太好了,它非常适合将滑块绑定到我的 KO 模型中的奇异值:

ko.bindingHandlers.slider = {
    init: function (element, valueAccessor, allBindingsAccessor) {
        var options = allBindingsAccessor().sliderOptions || {};
        $(element).slider(options);
        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);

    }
};

这就是我卡住的地方。例如,是否可以分配一个 valueAccessors 数组,这样我就可以执行以下操作:

<div id="sliderTerms" data-bind="rangeSlider: [MinTerm, MaxTerm], sliderOptions: {min: 6, max: 120, range: true, step: 1}"></div>

谢谢!

4

3 回答 3

1

我根据你的写了我自己的,它是一个快速的模型,所以它可能有错误

http://jsfiddle.net/N9uwx/

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

        if(observable().splice) {
            options.range = true;        
        }        

        options.slide = function(e, ui) {
            observable(ui.values ? ui.values : ui.value);
        };

        ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
            $(element).slider("destroy");
        });

        $(element).slider(options);
    },
    update: function (element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor());
        $(element).slider(value.slice ? "values" : "value", value);

    }
};
于 2012-11-30T15:50:54.370 回答
0

谢谢!您的代码启发了我编写这个 bindingHandler:

ko.bindingHandlers.rangeSlider = {
    init: function (element, valueAccessor, allBindingsAccessor) {
        var options = allBindingsAccessor().sliderOptions || {};
        var observable = valueAccessor();

        ko.utils.registerEventHandler(element, "slidechange", function (event, ui) {
            observable[0](ui.values[0]);
            observable[1](ui.values[1]);
        });
        ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
            $(element).slider("destroy");
        });
        ko.utils.registerEventHandler(element, "slide", function (event, ui) {
            observable[0](ui.values[0]);
            observable[1](ui.values[1]);
        });

        $(element).slider(options);
    },
    update: function (element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor());
         if(value instanceof Array)
        {
            var value1= ko.utils.unwrapObservable(value[0]);
            var value2= ko.utils.unwrapObservable(value[1]);
            if(value1)
            {
                value = [value1, value2];
            }
            else value = 0;
        }
        else if (isNaN(value)) value = 0;
        $(element).slider(value.slice ? "values" : "value", value);
    }
}; 

现在我可以将 rangeSlider 绑定到我的 Knockout 模型,如下所示:

<div id="sliderTerms" data-bind="rangeSlider: [MinTerm, MaxTerm], sliderOptions: {min: 6, max: 120, range: true, step: 1, values: [6,120]}"></div>

这有点臭,因为我认为 values[i] 应该绑定到 valueAccessor[i] 但这对我来说已经足够了。

于 2012-12-03T10:57:39.087 回答
0

对于@Nico Beemster 在他自己的代码中发现的错误,我们需要“更新” update: 部分,如下所示:

 update: function (element, valueAccessor, allBindingsAccessor) {
            console.log("update fired");
            var value = ko.utils.unwrapObservable(valueAccessor());
              if(value instanceof Array)
        {
            var value1= ko.utils.unwrapObservable(value[0]);
            var value2= ko.utils.unwrapObservable(value[1]);
            if(value1)
            {
                value = [value1, value2];
            }
            else value = 0;
        }
        else if (isNaN(value)) value = 0;
            $(element).slider(value.slice ? "values" : "value", value);
             $(element).slider("option", allBindingsAccessor().sliderOptions);
        }

是更新的小提琴。如果您想更新最大和最小范围元素(如果它们是可观察元素)。

于 2014-12-22T18:01:58.080 回答