Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can i update a observable in custom bindings?

Tags:

knockout.js

I am having a binding handler with simple logic inside where i will update the observable so it will update itself in view .

This i a sample case where everything works as expected

My View :

<input data-bind="value: name" />
<hr/>
<div data-bind="fadeInText: name"></div>

Code :

ko.bindingHandlers.fadeInText = {
    update: function(element, valueAccessor) {
        ko.bindingHandlers.text.update(element,valueAccessor);//text becoz its binded to div
    } 
};

Here I'm trying to do something like this(below) and i am stuck here updating a observable

My view :

<input data-bind="value: name" />
<hr/>
<input type="text" data-bind="fadeInText: name" />
<div data-bind="text:ko.toJSON($data)"></div>

Code:

ko.bindingHandlers.fadeInText = {
    update: function(element, valueAccessor) {
            var value = valueAccessor();
    ko.bindingHandlers.value.update(element,valueAccessor);
    $(element).change(function () {
            value($(element).fadeInText('get'));
        });
    } 
};

In this given scenario there are two textboxes when i update a value in textbox-1 then textbox-2 value is getting updated .

But when i try to update textbox-2 value nothing gets updated i feel so close but for now i can't crack this up .

Checked chrome console i see Uncaught TypeError: undefined is not a function but fadeInText is present in binding

Update :

I tried allBindingsAccessor().fadeInText() i get the old value everytime not the new entered one .

Fiddler provided here

There is something with same way done but its working fiddler here.

Any help on this one is great .

like image 809
super cool Avatar asked Jan 24 '15 17:01

super cool


1 Answers

If you want to wrap the value binding, you must call its init as well:

ko.bindingHandlers.fadeInText = {
    init: function(element, valueAccessor, allBindings) {
        ko.bindingHandlers.value.init(element,valueAccessor, allBindings);
    },
    update: function(element, valueAccessor) {  
       var value = valueAccessor();
       ko.bindingHandlers.value.update(element,valueAccessor);
    } 
};

Working fiddle.

Here's why: your fadeInText update handler is called automatically when the name observable changes - accessing it in the update handler registers it. So one half of the two-way binding — observable to input field — works.

For the other half of the two-way binding — input field to observable — you need to call the init handler of the value binding, because that is where value sets up the event handler for it to be notified when the input field changes.

As a rough rule of thumb, you use the init part of a custom binding for the code that changes the observable when the HTML element has changed (e.g. by attaching event handlers), and the update part to change the HTML element when the observable has changed.

like image 148
janfoeh Avatar answered Sep 17 '22 18:09

janfoeh