Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initialize Knockout observable from element attribute value

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/

like image 634
KodeKreachor Avatar asked Jul 17 '12 15:07

KodeKreachor


People also ask

How do I set observable value in Knockout?

To create an observable, assign the ko. observable function to the variable. A default value can be specified in the constructor of the call. Knockout then converts your variable into a function and tracks when the value changes, in order to notify the UI elements associated with the variable.

What is Ko observable ()?

An observable is useful in various scenarios where we are displaying or editing multiple values and require repeated sections of the UI to appear and disappear as items are inserted and deleted. The main advantage of KO is that it updates our UI automatically when the view model changes.

How do we activate a Knockout model?

To activate Knockout, add the following line to a <script> block: ko. applyBindings(myViewModel); You can either put the script block at the bottom of the HTML document, or you can put it at the top and wrap the contents in a DOM-ready handler such as jQuery's $ function.

How do you declare a viewModel property as observable?

Syntax. You just need to declare ViewModel property with function ko. observable() to make it Observable.


2 Answers

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.

like image 183
Kyeotic Avatar answered Sep 29 '22 02:09

Kyeotic


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...

like image 20
Master Morality Avatar answered Sep 29 '22 04:09

Master Morality