evento lostfocus / onblur en nocaut


Quiero ejecutar un evento en un observable knockout vinculado a un input. Esta función debe ejecutarse cuando el control pierde el foco, incluso sin escribir nada. Traté de cambiar el enlace de eventos, pero no se dispara cuando el usuario se aleja del control sin escribir nada. He intentado mouseout evento, pero que solo se dispara cuando el usuario hace clic en otro lugar en el formulario, después de perder el foco-no es exactamente lo que quiero. Quiero que el incluso para disparar tan pronto como el foco se aleja de la control, incluso con tab.

El siguiente es el código que usé para el evento mouseout:

<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');
    }
}

¿Puede alguien ayudar por favor?

Author: Gab, 2013-04-19

6 answers

Creo que hay algunos enfoques que podría utilizar. Una buena opción sería usar KO hasfocus binding: http://knockoutjs.com/documentation/hasfocus-binding.html .

Puede enlazar contra un observable booleano, y luego suscribirse a él. En la suscripción, puede elegir reaccionar solo cuando el valor ahora es false.

Algo como:

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
   }
});

Atad contra ella como:

data-bind="value: FirstName, hasfocus: FirstName.focused"

Creo que esta sería una buena opción si quieres que se dispare cada vez que un usuario abandona el campo sin importar cómo lo abandone e independientemente de si realmente se realizó un cambio.

 31
Author: RP Niemeyer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-20 14:41:13

Me gusta la respuesta de @RPNiemeyer. Sin embargo, solo quería señalar que no todo tiene que hacerse por Nocaut. Es solo una herramienta, y a veces no es la mejor herramienta para el trabajo. Usted siempre acaba de usar enlace de eventos directos como siempre lo ha hecho en JS, es decir,

$('#FirstName').on('blur', function () {
    // do something
});

Si realmente necesita interactuar con su modelo de vista allí, entonces simplemente puede usar ko.dataFor como se describe en la documentación de Knockout sobre la delegación de eventos :

$('#FirstName').on('blur', function () {
    var data = ko.dataFor(this);
    // do something with data, i.e. data.FirstName()
});
 21
Author: Chris Pratt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-19 14:55:00

Esto funcionó para mí:

data-bind="event: { blur: OnBlurEvent }"
 18
Author: arntjw,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-20 10:08:59

Acabo de tener el mismo problema, resuelto mediante la creación de un enlace personalizado:

ko.bindingHandlers.modifyOnFocusOut = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        $(element).blur(function() {
            //Do your work
        });
    }
}

Y luego lo llamó así:

 data-bind="value: FirstName, modifyOnFocusOut: FirstName"
 5
Author: jfc37,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-14 05:14:58

¿Ha intentado event:{blur: ValidateFirstName} este evento se disparará si el usuario hace clic en out o 'tab out' de la entrada.

<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}"

Aquí hay un JSFiddle de un ejemplo de trabajo.

 3
Author: Gab,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-25 14:32:44

Usando TypeScript lo resolví usando 2 enlaces personalizados, un SetFocusBinding y un Enlace OnBlur... Usando el SetFocusBinding me aseguro de que el campo de entrada tenga foco. Usando el enlace OnBlur, se llama a una función cuando se activa el evento de desenfoque.

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();
        }
    }
}

Y ...

    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();
 0
Author: Paul0515,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-16 09:44:34