Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
271 views
in Technique[技术] by (71.8m points)

javascript - Get element an observable is bound to with Knockout?

This isn't an ideal situation, but due to another knockout binding I am using I am in a situation where I am needing to get the element an observable is bound to, if it is indeed bound to anything.

So is there a way to do this?

== Update ==

I didn't want to add any extra context incase it confuses the question, but as it may get an answer more in line with expectations here is the scenario.

I am using the knockout validation binding, which exposes all the errors using the ko.validation.group(model) method. However the problem is that only gives you the textual errors, it does not give you any context as to what part of the model gave you those errors. So I have made a small change to the source to now pass back the observable tied to each error, as this may be useful for a few scenarios, but from here I need to be able to tie this to an element so I can display some in-line validation of some kind.

Knockout Validation provides a very basic in-line validation where it creates a span after your element and you can give it a class, but this is too basic for my needs as currently we are using Qtip and other notification systems to display validation errors, and because of this I need to be able to have a Dom element and an error. So far I have an observable and an error, but I need to tie that observable object (which could be any ko.observable() property from the model) to its given DOM element, if it does have an element binding.

As all I have is an object and I am using validation driven from the model not the UI, the problem is not really going to be solved via a custom binding. Ideally I need to be able to crack open the marry up the observable object (an unknown ko.observable()) to an element.

Not to go too project specific, but my current project abstracts validation where events are fired off (i.e EventSystem.SendEvent(ValidationEvents.ValidationFailed, <element>, <error>)) then a validation system listens for these events and ties the error to the element, be it a tooltip, a growl style notification, an alert box etc. So I am trying to find the best way to keep this abstraction when driving the validation from the models observables not the ui's DOM elements (i.e jquery-ui)

== Edit 2 ==

I was a bit thrown by the way Knockout Validation knows the elements for observables to put in its own validation elements, however they just piggy back off the existing value binding, so I am just going to change that to add the elements for any validation elements based on their isValidatable() method, at least that way for each error I can tie it to an observable, and for any observables with element bindings I can tie them to the elements, and if there are none then it is fine they would just be form wide validation errors. I will give this a try as this should be something like (not tested yet):

if(utils.isValidatable(valueAccessor())) {
    valueAccessor().extend({hasElementalBinding: true, elementalBinding: element});
}
else { 
    valueAccessor().extend({hasElementalBinding: false});
}

At around line 250 in the registerValueBindingHandler, I will leave this question open for a while longer incase someone else has a better solution.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I have done something similar to what you mentioned above. My data-bind tag includes a custom binding:

data-bind="... myvalidationbinding: myobservable"

Then in my binding handler I extend the observable

ko.bindingHandlers.myvalidationbinding = {
  init: function (element, valueAccessor, allBindingsAccessor, viewModel) { 
    valueAccessor().extend({element: element });
  }
};

And finally my extension is

ko.extenders.element = function (target, element) {
  target.DOMElement = element;
}

Now I can subscribe to isValid() given by knockout.validation and if not valid, go get the element the observable is bound to and then manipulate it with jQuery.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...