【问题标题】:<input> lostfocus/onblur event in knockout<input> 淘汰赛中的 lostfocus/onblur 事件
【发布时间】:2013-04-12 16:16:39
【问题描述】:

我想在绑定到input 的淘汰赛 observable 上执行一个事件。这个函数应该在控件失去焦点时执行,即使没有输入任何内容。我试图更改事件绑定,但是当用户离开控件而不键入任何内容时它不会触发。我尝试了 mouseout 事件,但只有当用户在失去焦点后单击表单中的其他位置时才会触发 - 这不是我想要的。我希望在焦点从控件移开后立即触发,即使使用选项卡也是如此。

以下是我用于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');
    }
}

有人可以帮忙吗?

【问题讨论】:

    标签: knockout.js mouseout event-binding


    【解决方案1】:

    我认为您可以使用几种方法。一个不错的选择是使用 KO 的 hasfocus 绑定:http://knockoutjs.com/documentation/hasfocus-binding.html

    你可以绑定一个 boolean observable,然后订阅它。在订阅中,您可以选择仅在该值为 false 时做出反应。

    类似:

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

    像这样绑定它:

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

    我认为,如果您希望它在每次用户离开该字段时触发,无论他们如何离开,也无论是否实际进行了更改,这将是一个不错的选择。

    【讨论】:

    • +1:我的天啊,我一直在砍和破解我编写的几乎完全一样的代码。我一生都无法弄清楚到底有什么不同之处可以在我没有自己写的答案中起作用。我输入了data-bind="text 而不是data-bind="value。感谢您在答案中添加绑定声明。显然,我今天需要踢裤子。
    • @JoelEtherton - 我自己肯定没有做过一两次。很高兴你明白了。
    • 我已经尝试过这种技术。对我来说,问题在于 hasFocus 似乎总是在初始页面加载时“触发”(变为 true),这使得我正在尝试做的一切都处于错误的状态。我将相应的 viewmodel 值初始化为 false,但这并没有改变任何东西。
    • 哎呀,刚刚发现任何焦点变化——包括失去焦点——都会导致绑定值发生变化。所以我只需要询问 newValue 以查看焦点是真还是假。它有一个事件名称('focus')让我忘记了 observables 是如何工作的。 :)
    • 我在使用这种方法时遇到了问题。我认为这是因为我有多个输入字段绑定到同一个可观察对象。发生的情况是,事情被触发了四次,newValue 在真假之间来回切换。只会使用 jquery blur。
    【解决方案2】:

    这对我有用:

    data-bind="event: { blur: OnBlurEvent }"
    

    【讨论】:

    • 如果这就是你想要的,我敢说这是最好的方法。我想知道@rp-niemeyer 对此有何看法。他肯定会想到这种方法吗?
    【解决方案3】:

    我喜欢@RPNiemeyer 的回答。但是,我只想指出,并非所有事情都必须通过 Knockout 完成。它只是一个工具,有时它并不是工作的最佳工具。你总是像在 JS 中那样使用直接事件绑定,即

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

    如果您需要在那里与您的视图模型进行实际交互,那么您可以简单地使用ko.dataFor,如Knockout's documentation on event delegation 中所述:

    $('#FirstName').on('blur', function () {
        var data = ko.dataFor(this);
        // do something with data, i.e. data.FirstName()
    });
    

    【讨论】:

    • 我更喜欢这个解决方案,因为它不添加任何订阅。 :)
    【解决方案4】:

    我刚刚遇到了同样的问题,通过创建自定义绑定解决了它:

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

    然后这样称呼它:

     data-bind="value: FirstName, modifyOnFocusOut: FirstName"
    

    【讨论】:

      【解决方案5】:

      您是否尝试过event:{blur: ValidateFirstName} 如果用户点击或“跳出”输入,则会触发此事件。

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

      这是一个工作示例的JSFiddle

      【讨论】:

        【解决方案6】:

        使用 TypeScript 我使用 2 个自定义绑定解决了它,一个 SetFocusBinding 和一个 OnBlur 绑定...使用 SetFocusBinding 我确保输入字段具有焦点。使用 OnBlur 绑定在触发模糊事件时调用函数。

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

        和...

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

        【讨论】:

          猜你喜欢
          • 2018-02-27
          • 2013-01-31
          • 1970-01-01
          • 1970-01-01
          • 2015-02-24
          • 2012-05-22
          • 2013-09-10
          • 1970-01-01
          • 2022-10-17
          相关资源
          最近更新 更多