Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Knockout with multiple valueUpdates

Tags:

knockout.js

I'm a newbie when it comes to using knockout, I really want to maximize it's usage in the web that I am developing. But I am having concerns when it comes to the browsers capability to listen to multiple user events. I believe that knockout implements a property called valueupdate. So far, I have only used 'afterkeydown' and 'blur'. But I need my browser to listen to multiple events at the same time. Below are the user events that my browser should listen to:

  1. On page load, I want my input fields to start validating on page load.
  2. On blur, I want my input fields to validate after it losts focus.
  3. After key down, I also want my fields to re-validate them selves after the user presses a key.
  4. On submit, though my fields are not wrapped in a form, I still want to validate my fields, after the user clicks the "Save" button.

I'm thinking of something like this:

<input data-bind="value:someObservable, valueUpdate:'blur' + 'afterKeyDown' + 'onLoad' + 'onClickOfSaveButton'" />

--> Something like that, though I know this will cause a syntax error, but I hope you get my point.

I know, this question is kinda confusing, but if you want more details, please don't hesitate to specify it on your comment. I really need help here. Thanks.

like image 648
Lemuel Nitor Avatar asked Jun 03 '13 01:06

Lemuel Nitor


People also ask

Can we have multiple knockout model?

Knockout now supports multiple model binding. The ko. applyBindings() method takes an optional parameter - the element and its descendants to which the binding will be activated.

What is applyBindings in knockout?

applyBindings do, The first parameter says what view model object you want to use with the declarative bindings it activates. Optionally, you can pass a second parameter to define which part of the document you want to search for data-bind attributes. For example, ko.

Which function is used for computation in knockout?

In some scenarios, it is useful to programmatically determine if you are dealing with a computed observable. Knockout provides a utility function, ko. isComputed to help with this situation. For example, you might want to exclude computed observables from data that you are sending back to the server.

Is knockout a library or framework?

Knockout. js is an open source library (under the MIT License) that is pure JavaScript that works with any existing web framework and every mainstream browser. Further, Knockout. js is fully documented with a complete set of online tutorials.


1 Answers

Always happy to see a 'newbie' decide to make the switch to KnockoutJS. Anything that can help rid the world of verbose, ad hoc data-binding solutions is a wonderful thing.

To answer your question regarding how to key off multiple events to update your data-binding value, you would write:

<input data-bind="value:someObservable, valueUpdate: ['blur', 'afterKeyDown', 'onLoad']"/>

In my case, I was using a bootstrap typeahead to select a value, but the data-binding was not being refreshed after the user made a selection from the dropdown suggestion box. After looking at the source, I found this little hidden gem that was not mentioned on the KO docs.

I cringe telling anyone to "go read the source", but if you're dealing with a fringe case that isn't covered in the docs, don't be scared to! I've uncovered many undocumented features by doing so

source: https://github.com/knockout/knockout/blob/master/src/binding/defaultBindings/value.js

ko.bindingHandlers['value'] = {
    'init': function (element, valueAccessor, allBindingsAccessor) {
        // Always catch "change" event; possibly other events too if asked
        var eventsToCatch = ["change"];
        var requestedEventsToCatch = allBindingsAccessor()["valueUpdate"];
        var propertyChangedFired = false;
        if (requestedEventsToCatch) {
            // Allow both individual event names, and arrays of event names
            if (typeof requestedEventsToCatch == "string")       
                requestedEventsToCatch = [requestedEventsToCatch];
            ko.utils.arrayPushAll(eventsToCatch, requestedEventsToCatch);
            eventsToCatch = ko.utils.arrayGetDistinctValues(eventsToCatch);
        }
    .... truncated ....

Depending on your familiarity with writing bindings, it may be fairly apparent that the valueUpdate binding handles an array of events. Here they're getting the supplemental binding "valueUpdate" and storing it in var requestedEventsToCatch . The next comment marks the logic to handle an array of events to update the value on -- indeed they cast even a single event such as "afterKeyDown" to ["afterKeyDown"]

Hope this helps!

like image 97
matrix10657 Avatar answered Nov 08 '22 05:11

matrix10657