简体   繁体   中英

Subscribe to bindings of an existing DOM element in KnockoutJS

I need to subscribe to an existing binding of a DOM element. As an example, I have the following input element:

<div id="MyDiv">
    <input id="MyInput" data-bind="enable: isEnabled()" />
</div>

Now, assuming I only have access to the DOM element, I need to do something like this:

var inputElement = $("#MyInput");
var bindings = ko.utils.getBindings(inputElement); // getBindings does not exist
var enableBinding = bindings["enable"];
if (enableBinding != undefined) {
    enableBinding.subscribe(function (value) {
        if (value == false)
            $("#MyDiv").addClass("disabled");
        else
            $("#MyDiv").removeClass("disabled");
    })
}

Is there a way to do this?

Update: I've extended the sample so that you see my use case for this: The div here is automatically generated by a preprocessor and needs the disabled class on it when the input is disabled. It does not work if the attribute is only changed on the input element. The addition/removal must be transparent...

Short answer: Don't do this. There is a reason that getBindings is not a particularly visible function in the Knockout toolkit.

Long answer: You can, through a bit of indirection, get at the original binding.

HTML:

<div id="MyDiv">
    <input id="MyInput" data-bind="enable: isEnabled" />
</div>

<input type="checkbox" data-bind="checked: isEnabled" />

JS:

var viewModel = function() {
    self.isEnabled = ko.observable(true);           
}

ko.applyBindings(new viewModel());

var input = $('#MyInput')[0];

function getBinding(element, name) {
    var bindings = ko.bindingProvider.instance.getBindings(input, ko.contextFor(input));

    return bindings.hasOwnProperty(name) ? bindings[name] : null;
}

var binding = getBinding(input, 'enable');

binding.subscribe(function(value) {
    if (value == false)
        $("#MyDiv").addClass("disabled");
    else
        $("#MyDiv").removeClass("disabled");
});

Working JSFiddle

EDIT: Found a shorter way

Again, if there is any way you can convince your preprocessor to add a CSS observable, do so. Mucking about with bindings in this manner relies on the particular quirks of Knockout 3.3.0's internal implementation, which can change in future releases.

Checkout the answer provided here .

In short, you can use

var viewModel = ko.dataFor(domElement);

to get the viewmodel that is bound to that DOM element. You can then, subscribe to any observables attached to that viewmodel.

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