2013-04-19 12 views
24

ノックアウト観測値のイベントをinputにバインドして実行します。この関数は、何も入力しなくても、コントロールがフォーカスを失ったときに実行する必要があります。私はイベントバインディングを変更しようとしましたが、ユーザが何も入力せずにコントロールから離れると起動しません。私はmouseoutイベントを試しましたが、フォーカスが失われた後、ユーザーがフォーム内の他の場所をクリックしたときにのみ発生します。私はフォーカスがタブからでもコントロールから離れるとすぐに射撃をしたい。続き<input>ノックアウトのlostfocus/onblurイベント

は私がマウスアウトイベントに使用されるコードです:

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

誰も助けてくださいことはできますか?

答えて

31

私はあなたが使用できるいくつかのアプローチがあると思います。良いオプションは、KOのhasfocusバインディングを使用することです:http://knockoutjs.com/documentation/hasfocus-binding.html

ブールオブザーバブルにバインドしてサブスクライブすることができます。サブスクリプションでは、値が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" 

は毎回ユーザーがどんなにフィールドを残しません彼らはそれを残し、変更が実際になされたかどうかにかかわらず。

+0

1:OMG私はチョッピングと私は非常に近く、まさにこのように書いたコードのスニペットでハッキングされてきました。私は自分の人生のために、私が自分自身を書いていなかったあなたの答えに働く地球上で何が違うのかを理解できませんでした。私は 'data-bind =" value "の代わりに' data-bind = "text"を入力に持っていました。あなたの答えにバインディングステートメントを追加してくれてありがとう。今日は明らかにズボンにキックが必要でした。 –

+0

@JeelEtherton - 私は間違いなくそれを1〜2時間はやったことがありません。あなたがそれを理解してうれしいです。 –

+0

私はこの手法を試しました。問題は、私にとっては、hasFocusは最初のページの読み込み時に常に「発動」する(真になる)ように見えるため、すべてのことを間違った状態にしています。対応するviewmodelの値をfalseに初期化しますが、これは何も変わりません。 –

21

@ RPNiemeyerの回答が好きです。しかし、私はちょうど指摘したかったすべてはノックアウトを介して行う必要があります。それは単なるツールであり、時にはそれは仕事にとって最善のツールではありません。あなたは常にあなたが実際にそこにあなたのビューモデルと対話する必要がある場合Knockout's documentation on event delegationで説明したように、その後、あなたは、単にko.dataForを使用することができ、すなわち

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

、あなたは常にJSでやったように結合直接イベントを使用します。

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

私はこのソリューションが少し好きです。サブスクリプションを追加しないからです。 :) – Josh

5

私は、同じ問題を抱えていたカスタムバインディングを作成することによって、それを解決:

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

そして、このようにそれを呼ばれる:

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

これは私の仕事:

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

これがあなたが欲しいのなら、これが最善の方法だと私は敢えて言います。私は@ rp-niemeyerがこれについて何を考えているのだろうか。確かにこのアプローチは彼の心を横切った? – aaaidan

3

は、ユーザーが出てクリックするか、入力の「タブのうち」場合は、このイベントが発生します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です。

0

TypeScriptを使用して、2つのカスタムバインディング、SetFocusBinding、およびOnBlur Bindingを使用して解決しました。SetFocusBindingを使用して、入力フィールドにフォーカスがあることを確認します。 OnBlurバインディングを使用すると、blurイベントがトリガされたときに関数が呼び出されます。

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(); 
関連する問題