initialize viewModel from DOM elements

384 views
Skip to first unread message

Binish

unread,
Sep 7, 2011, 8:09:29 AM9/7/11
to KnockoutJS
is there anyway to initialize viewModel from DOM elements?

<div class="question"><label for="textItem" data-bind="text:
itemLabel">Text </label></div>
<div class="field">
<input type="text" id="textItem1"
name="textItem" data-bind="attr: { id: itemId , name: itemSASName }"/>
</div>
<div class="settings-tmpl" >
</div>


from above DOM update my viewModel which is empty

rpn

unread,
Sep 7, 2011, 9:15:36 AM9/7/11
to knock...@googlegroups.com
Hello-
It is possible to write custom bindings that will populate your view model.  There have been a few threads that discussed ideas for this like here and here.

Here is a sample of a "valueWithInit" binding that will take the existing value of an input and populate the view model with it.  If the property does not exist on the view model, then it will be created as an observable.


ko.bindingHandlers.valueWithInit {
    initfunction(elementvalueAccessorallBindingsAccessorcontext{
        var property valueAccessor();
        var value $(element).val();

        //create the observable, if it doesn't exist 
        if (!ko.isWriteableObservable(context[property]){
            context[propertyko.observable();
        }
        context[property](value);
        ko.bindingHandlers.value.init(elementfunction(return context[property]},allBindingsAccessorcontext);
    },
    updatefunction(elementvalueAccessorallBindingsAccessorcontext{
        var property valueAccessor();
        ko.bindingHandlers.value.update(elementfunction(return context[property];},allBindingsAccessor);
    }
};

Binish

unread,
Sep 7, 2011, 12:31:17 PM9/7/11
to KnockoutJS
Thanks rpn!!

I created for all I needed.

one thing to note that properties should be mentioned in quotes

ko.bindingHandlers.textWithInit = {
init: function(element, valueAccessor, allBindingsAccessor,
context) {
var property = valueAccessor();
var value = $(element).text();
//create the observable, if it doesn't exist
if (!ko.isWriteableObservable(context[property])) {
context[property] = ko.observable();
}
context[property](value);

},
update: function(element, valueAccessor, allBindingsAccessor,
context) {
var property = valueAccessor();
ko.bindingHandlers.text.update(element, function() {
return context[property];
}, allBindingsAccessor);
}
};
ko.bindingHandlers.htmlWithInit = {
init: function (element, valueAccessor, allBindingsAccessor,
context) {
var property = valueAccessor();
var value = $(element).html();
//create the observable, if it doesn't exist
if (!ko.isWriteableObservable(context[property])) {
context[property] = ko.observable();
}
context[property](value);

},
update: function (element, valueAccessor, allBindingsAccessor,
context) {
var property = valueAccessor();
ko.bindingHandlers.html.update(element, function () {
return context[property];
}, allBindingsAccessor);
}
};
ko.bindingHandlers.attrWithInit = {
init: function (element, valueAccessor, allBindingsAccessor,
context) {
var value = ko.utils.unwrapObservable(valueAccessor()) || {};
for (var attrName in value) {
if (typeof attrName == "string") {
var attrValue = element.getAttribute(attrName);
var property = valueAccessor()[attrName];
//create the observable, if it doesn't exist
if (!ko.isWriteableObservable(context[property])) {
context[property] = ko.observable();
}
context[property](attrValue);
}
}
},
update: function (element, valueAccessor, allBindingsAccessor,
context) {
var value = ko.utils.unwrapObservable(valueAccessor()) || {};
for (var attrName in value) {
if (typeof attrName == "string") {
var property = valueAccessor()[attrName];
var attrValue = context[property]();//
ko.utils.unwrapObservable(value[attrName]);

// To cover cases like "attr: { checked:someProp }",
we want to remove the attribute entirely
// when someProp is a "no value"-like value (strictly
null, false, or undefined)
// (because the absence of the "checked" attr is how
to mark an element as not checked, etc.)
if ((attrValue === false) || (attrValue === null) ||
(attrValue === undefined))
element.removeAttribute(attrName);
else
element.setAttribute(attrName,
attrValue.toString());
}
}
}
};

On Sep 7, 3:15 pm, rpn <rnieme...@gmail.com> wrote:
> Hello-
> It is possible to write custom bindings that will populate your view model.
>  There have been a few threads that discussed ideas for this like here
> <https://groups.google.com/d/topic/knockoutjs/UahPJPzMuUU/discussion>and
> here <https://groups.google.com/d/topic/knockoutjs/K-xyD1PghMk/discussion>.
Reply all
Reply to author
Forward
Message has been deleted
0 new messages