3

For example, I want to bind a property in the viewmodel to an height of an element so if its height get changed it updates the property. I read this example but it shows only one direction binding: http://knockoutjs.com/documentation/style-binding.html , meaning updating the property will update the style but not otherwise.

What I am thinking of doing is something like that:

<div class="panel-body" data-bind="style: {height: chatParentHeight}">
   <div data-bind="style: { height: chatHeight}">
   </div>
</div>

In view model: self.chatParentHeight = ko.observable(); self.chatHeight = self.chatParentHeight();

So the parent height is monitored for changes and if a change happens it also changes the child element height because it's bound to it. But the viewmodel is not updated when the height style is updated. I tried also with backgroundColor to simplify it , but it doesn't work as well.

Ronen Festinger
  • 2,260
  • 1
  • 23
  • 32

2 Answers2

2

The question from your title can be answered using the Knockout source: it's open, and actually pretty easy to go through. To quote the relevant file:

ko.bindingHandlers['style'] = {
    'update': function (element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor() || {});
        ko.utils.objectForEach(value, function(styleName, styleValue) {
            styleValue = ko.utils.unwrapObservable(styleValue);

            if (styleValue === null || styleValue === undefined || styleValue === false) {
                // Empty string removes the value, whereas null/undefined have no effect
                styleValue = "";
            }

            element.style[styleName] = styleValue;
        });
    }
};

So the answer is "no": the style binding is not two-way, but then again it's also "yes" as you can write a custom binding handler to do this yourself.

If your question is actually different, more about how to have two heights related, then check out the other answer.

Community
  • 1
  • 1
Jeroen
  • 60,696
  • 40
  • 206
  • 339
1

Sure it's possible just use a ko computed in your view model.

self.chatParentHeight = ko.observable();
self.chatHeight = ko.computed(function(){
    return self.chatParentHeight();
});

the reason the child element is not changing in your view model is that the child element is not an observable at all, but rather when the view model is created it gets assigned the value of self.chatParentHeight. But because it's not actually an observable, the change event does not fire when the chatParentheight changes. The ko computed object creates a dependant observable to change the height, and automatically detects when the parent height changes and recomputes the value of chat height

theDarse
  • 749
  • 5
  • 13