简体   繁体   中英

knockout.js variable update on attr change

I've got a jQuery UI slider. When the user uses a slider, the slider updates an attr variable in the div tag of the slider

$(".slider").each(function() {
var value = parseInt($(this).attr('data-init-value'), 10);
var amin = parseInt($(this).attr('data-min'), 10);
var amax = parseInt($(this).attr('data-max'), 10);
console.log(value, " ", amin, " ", amax)
$(this).empty().slider({
    value : value,
    min : amin,
    max : amax,
    range : "min",
    animate : true,
    slide : function(event, ui) {
        $(this).attr('data-value', ui.value);
    }
});

});

The example div tag in the html:

<div class="slider" data-min="200" data-max="600" data-init-value="300" data-bind="attr: { 'data-value': someValue }"></div>

When the slider is changed the data-value is updated in the <div> but the js variable doesn't change. (in other, trivial binding cases - like text: - it works.)

How to bind this action?

I suggest you do this the other way around. Bind the value of the slider to an observable property on your viewmodel, and then bind the attribute to that observable.

Then you can always access the most recent value of the slider directly through the viewmodel, and the UI will stay up to date as well.

And further, if you want to subscribe to the update event of that observable, you can bind to that as well. Here is an example from the documentation :

myViewModel.personName.subscribe(function(newValue) {
    alert("The person's new name is " + newValue);
});

And finally, this might as well be a possible duplicate of: Identify the attribute change event in KnockoutJS?

-- Update to answer comments

Given the following viewmodel:

var viewModel = {
    mySliderValue: ko.observable(0)
};

Then, in your slider callback, you could do something like this:

viewModel.mySliderValue(value);

And then, in your view, having the following attr binding:

data-bind="attr: { 'data-value': mySliderValue }"

... will cause the UI to update when the observable changes its value.

PS. I suggest you no longer delete this thread since my answer is starting to deviate more and more from the one I linked to.

The way to do it is to register an event handler.

o.utils.registerEventHandler(element, "slidechange", function (event, ui) {
   var observable = valueAccessor();
   observable(ui.value);
});

JSFiddle for full example: http://jsfiddle.net/snLk8/3/

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