简体   繁体   中英

Getting knockout computed observables to fire from jQuery slider control

I have a custom knockout binder for the jQuery slider control. The slider is updating the currentPage observable, but the generic ko.computed that is dependent upon currentPage() never fires. Why is this and how can it be fixed so that the generic is fired?

I found this technique for using async ajax calls with knockout here... Asynchronous Dependent Observables . Evidently the dependentObservable has been replaced by the computed . I was able to get it to work with dependentObservable or with computed.deferEvaluation=false , but I need deferEvaluation=true so the ajax call isn't fired multiple times.

Fiddle http://jsfiddle.net/jeljeljel/3WN6v/

HTML

<div style="margin:10px;" data-bind="slider: currentPage, sliderOptions: {min: 0, max: 10, range: 'min'}"></div>

<div id="plugin" data-bind="template: { name: 'template1', data: $data }" ></div>

<script type="text/html" id="template1">
        <span data-bind="text: displayText"></span>
</script>

Javascript

// create ko custom binding handler for slider control
ko.bindingHandlers.slider = {
    init: function (element, valueAccessor, allBindingsAccessor) {
        var options = ko.toJS(allBindingsAccessor().sliderOptions) || {};
        $(element).slider(options);
        ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
            $(element).slider('destroy');
        });
        ko.utils.registerEventHandler(element, 'slidechange', function (event, ui) {
            var observable = valueAccessor();
            observable(ui.value);
        });
    }
};

function DataModel() {
    var self = this;
    self.currentPage = ko.observable(0);
    self.displayText = ko.observable(0);

    ko.computed({
        read: function () {
            $.ajax({
                url: '/echo/json/',
                //data: { page: currentPage() },
                success: function(){
                    self.displayText(currentPage());
                }
            });
        },
        deferEvaluation: true
    });
}

dataModel = new DataModel();
ko.applyBindings(dataModel);

You're not actually updating the displayText in your slider change event, as the valueAccessor that you are sending in to the binding event is the property that you are binding to the slider, namely, currentPage. Change the signature of the custom binding to include the viewModel, and then use that to update the value of displayText:

// create ko custom binding handler for slider control
ko.bindingHandlers.slider = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var options = ko.toJS(allBindingsAccessor().sliderOptions) || {};
        $(element).slider(options);
        ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
            $(element).slider('destroy');
        });
        ko.utils.registerEventHandler(element, 'slidechange', function (event, ui) {
            viewModel.displayText(ui.value);
        });
    }
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM