Initialize Knockout observable from element attribute value
Asked Answered
P

2

14

I have an element that possesses an attribute whose value is bound to a knockout observable:

<text transform='matrix(1 0 0 1 1 1)' data-bind='attr:{transform:textTransform}'></text>

When the element loads I'd like the observable to contain the value defined on the dom element, however it instead loads as undefined and the attribute is removed from the dom element alltogether:

<text data-bind='attr:{transform:textTransform}'></text>

Is it possible to initialize the value of a knockout observable from a dom element attribute and persist the value of the dom element attribute as well?

UPDATE: http://jsfiddle.net/5Z2SC/10/

Prudi answered 17/7, 2012 at 15:49 Comment(0)
A
19

Another option would be to use a custom binding, and collect the current value of the element in the init function. This is much more reusable, in my opinion.

ko.bindingHandlers.transform = {
    init: function(element, valueAccessor) {
        valueAccessor()(element.getAttribute('transform'));
    },
    update: function(element, valueAccessor) {
        var value = valueAccessor();
        element.setAttribute('transform', ko.utils.unwrapObservable(value))
    }
};

Of course, yours will be more complicated, since you must be doing something with this transform property. That logic will probably want to go in the update section.

Aronoff answered 17/7, 2012 at 16:23 Comment(0)
G
5

the data-bind attributes are not parsed until you call ko.applyBindings(). So if you need to get attribute data off of your elements you can do it like this.

function MyModel(){
    this.textTransform = ko.observable($('#myElement').attr('transform'));
}

ko.applyBindings(new MyModel());

basically, you are grabbing the value of the attribute and setting it as the initial value of the observable. the data-bind attributes are meant to be a template, so initial or default values should be specified in your ViewModel.

the other option is to write a custom binder, that can store a default if the observable returns null...

Germaine answered 17/7, 2012 at 16:2 Comment(1)
Thanks, but I went with the custom binding handler. Hard-coded default values for the initialized observables aren't what I'm looking for in this case as the element attribute value will be different depending on which one is loaded.Prudi

© 2022 - 2024 — McMap. All rights reserved.