Search code examples
knockout.jsknockout-2.0knockout-validation

see all extenders and custom bindings for observable


Is it possible to see all extenders and bindings attached to an observable within Knockout JS?

Sample View Model:

var viewModel = function(){
  var self = this;

  self.firstName = ko.observable().extend({required: "Please enter a name",
                                           logChange: "first name" });

  self.lastName = ko.observable().extend({ required:true});

}

I am also using several custom bindingHandlers including the Knockout X-Editable Plugin in addition to the KO Validation Plugin

Sample Multi-Page View:

  <!--Screen 1 -->
  <input data-bind="value:firstName"/>

   ....

  <!--Screen 2 -->
  <span data-bind="editable:firstName"></span>

A. Is there a way to query self.firstName() and get a list of all of the extenders?

{required: "Please enter a name", logChange: "first name" }

B. Is there another query that I can run to get all of the bindings handlers that depend upon this observable? Can this be returned as DOM elements?

Basically I am trying to display validation errors for imported data, but I want to append them below <span data-bind="editable"/> if I am on the 2nd view.

This is simple enough when validating each input individually, but it's getting complicated when using ko.validation.group(viewModel). Even if I iterate over every error, I'm not seeing how I can relate them with the original observable that threw the error.


Solution

  • There is a custom binding you can use

    <span data-bind="validationMessage: myObservable"></span>
    

    If that is not enough then you have to get creative :D

    There is no generic way of seeing all extenders on a observable. KO validation adds a few functions and observables to the extended observable that you can use

    • clearError
    • error
    • isValid
    • isValidating
    • rules
    • setError

    You need to create a custom binding to be able to see all bindings attached to a element. This is not a bad thing, its bad practice to have dependencies to the View from the ViewModel. From your custom binding init or update function you have a allBindingsAccessor

    ko.bindingHandlers.myBinding = {
        init: function(element, accessor, allBindingsAccessor) {
           var valueAttachedToCheckedBinding = ko.utils.unwrapObservable(allBindingsAccessor().checked);
        }
    }