问题
I want to execute an event on a knockout observable bound to an input
. This function should be executed when the control lose focus, even without typing anything. I tried to change the event binding but it doesn't fire when the user moves away from the control without typing anything. I tried mouseout event, but that only fires when the user clicks elsewhere in the form, after losing focus - not exactly what I want. I want the even to fire as soon as the focus is moved away from the control, even with tab.
Following is the code I used for mouseout event:
<input
type="text"
id="txtFirstName"
tabindex="1"
maxlength="25"
class="txtbox"
style="width: 200px;"
data-bind="value: FirstName,
attr: {title: FirstNameErrorMessage },
css: {validationFailed: !IsValidFirstName() },
event: {mouseout: ValidateFirstName}"
/>
this.ValidateFirstName = function () {
self.IsValidFirstName(true);
self.FirstNameErrorMessage('');
if (self.FirstName() == '') {
self.IsValidFirstName(false);
self.FirstNameErrorMessage('First Name is required');
}
}
Can anyone help please?
回答1:
I think that there are a few approaches that you could use. A nice option would be to use KO's hasfocus
binding: http://knockoutjs.com/documentation/hasfocus-binding.html.
You can bind against a boolean observable, and then subscribe to it. In the subscription, you can choose to only react when the value is now false.
Something like:
self.FirstName = ko.observable();
self.FirstName.focused = ko.observable();
self.FirstName.focused.subscribe(function(newValue) {
if (!newValue) {
//do validation logic here and set any validation observables as necessary
}
});
Bind against it like:
data-bind="value: FirstName, hasfocus: FirstName.focused"
I think that this would be a good option if you want it to fire everytime a user leaves the field no matter how they leave it and regardless of whether a change was actually made.
回答2:
I like @RPNiemeyer's answer. However, I just wanted to point out that not everything has to be done via Knockout. It's just a tool, and sometimes it's not the best tool for the job. You an always just use direct event binding like you've always done in JS, i.e.
$('#FirstName').on('blur', function () {
// do something
});
If you need to actually interact with your view model in there, then you can simply use ko.dataFor
as described in the Knockout's documentation on event delegation:
$('#FirstName').on('blur', function () {
var data = ko.dataFor(this);
// do something with data, i.e. data.FirstName()
});
回答3:
This worked for me:
data-bind="event: { blur: OnBlurEvent }"
回答4:
I just had the same problem, solved it by creating a custom binding:
ko.bindingHandlers.modifyOnFocusOut = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
$(element).blur(function() {
//Do your work
});
}
}
And then called it like this:
data-bind="value: FirstName, modifyOnFocusOut: FirstName"
回答5:
Have you tried event:{blur: ValidateFirstName}
this event will be fired if the user click out or 'tab out' of the input.
<input
type="text"
id="txtFirstName"
tabindex="1"
maxlength="25"
class="txtbox"
style="width: 200px;"
data-bind="value: FirstName,
attr: {title: FirstNameErrorMessage},
css: {validationFailed: !IsValidFirstName()},
event: {blur: ValidateFirstName}"
Here's a JSFiddle of a working example.
回答6:
Using TypeScript I solved it using 2 custom bindings, a SetFocusBinding and a OnBlur Binding... Using the SetFocusBinding I make sure the input field has focus. Using the OnBlur binding a function is called when the blur event is triggered.
module Fx.Ko.Bindings {
export class SetFocusBinding implements KnockoutBindingHandler {
public update(element, valueAccessor, allBindingsAccessor) {
var value = valueAccessor();
var valueUnwrapped = ko.unwrap(value);
if (valueUnwrapped == undefined) {
return;
}
if (valueUnwrapped)
$(element).focus();
}
}
}
and ...
module Fx.Ko.Bindings {
export class OnBlurBinding implements KnockoutBindingHandler {
public init(element, valueAccessor, allBindings, viewModel, bindingContext) {
var value = valueAccessor();
$(element).on('blur', function (event) {
value();
});
}
}
}
interface KnockoutBindingHandlers {
onBlur: KnockoutBindingHandler;
}
ko.bindingHandlers.onBlur = new Fx.Ko.Bindings.OnBlurBinding();
来源:https://stackoverflow.com/questions/16101763/input-lostfocus-onblur-event-in-knockout