フォーカスの紛失ではなく、KeypressのデータバインドにノックアウトJSを取得するにはどうすればよいですか?
-
10-10-2019 - |
質問
のこの例 ノックアウトJS フィールドと[[[タブ]]を編集すると、ビューモデルデータ、したがってフィールドの下のテキストが更新されるようになります。
ビューモデルデータがすべてのキープレスを更新するように、このコードを変更するにはどうすればよいですか?
<!doctype html>
<html>
<title>knockout js</title>
<head>
<script type="text/javascript" src="js/knockout-1.1.1.debug.js"></script>
<script type="text/javascript">
window.onload= function() {
var viewModel = {
firstName : ko.observable("Jim"),
lastName : ko.observable("Smith")
};
viewModel.fullName = ko.dependentObservable(function () {
return viewModel.firstName() + " " + viewModel.lastName();
});
ko.applyBindings(viewModel);
}
</script>
</head>
<body>
<p>First name: <input data-bind="value: firstName" /></p>
<p>Last name: <input data-bind="value: lastName" /></p>
<h2>Hello, <span data-bind="text: fullName"> </span>!</h2>
</body>
</html>
解決
<body>
<p>First name: <input data-bind="value: firstName, valueUpdate: 'afterkeydown'" /></p>
<p>Last name: <input data-bind="value: lastName, valueUpdate: 'afterkeydown'" /></p>
<h2>Hello, <span data-bind="text: fullName"> </span>!</h2>
</body>
から ドキュメンテーション
追加のパラメーター
ValueUpDate
バインディングにもValueUpDateというパラメーターが含まれている場合、これは、KOが変更を検出するために使用するブラウザイベントを定義します。次の文字列値は、最も一般的に有用な選択です。
「変更」(デフォルト) - ユーザーが異なるコントロールに焦点を移動したとき、または変更後すぐに要素の場合にビューモデルを更新します
「keyup」 - ユーザーがキーをリリースしたときにビューモデルを更新します
「キープレス」 - ユーザーがキーを入力したときにビューモデルを更新します。 KeyUpとは異なり、これはユーザーがキーを押し続けている間に繰り返し更新されます
- 「AfterKeyDown」 - ユーザーが文字の入力を開始するとすぐに、ビューモデルを更新します。これは、ブラウザのキーダウンイベントをキャッチし、イベントを非同期に処理することで機能します。
これらのオプションのうち、「AfterKeyDown」は、ビューモデルをリアルタイムで更新したい場合に最適な選択です。
他のヒント
の バージョン3.2 単に使用できます TextInputバインディング。:
<input data-bind="textInput: userName" />
それは2つの重要なことをします:
- すぐに更新します
- カット、ドラッグ、オートコンプリートのブラウザの違いを処理します...
したがって、追加のモジュール、カスタムコントロール、その他のものは必要ありません。
更新を行いたい場合 afterkeydown
「デフォルトでは」を注入できます valueUpdate
のバインディング value
バインディングハンドラー。新しいものを供給するだけです allBindingsAccessor
ハンドラーが使用するために afterkeydown
.
(function () {
var valueHandler = ko.bindingHandlers.value;
var getInjectValueUpdate = function (allBindingsAccessor) {
var AFTERKEYDOWN = 'afterkeydown';
return function () {
var allBindings = ko.utils.extend({}, allBindingsAccessor()),
valueUpdate = allBindings.valueUpdate;
if (valueUpdate === undefined) {
return ko.utils.extend(allBindings, { valueUpdate: AFTERKEYDOWN });
} else if (typeof valueUpdate === 'string' && valueUpdate !== AFTERKEYDOWN) {
return ko.utils.extend(allBindings, { valueUpdate: [valueUpdate, AFTERKEYDOWN] });
} else if (typeof valueUpdate === 'array' && ko.utils.arrayIndexOf(valueUpdate, AFTERKEYDOWN) === -1) {
valueUpdate = ko.utils.arrayPushAll([AFTERKEYDOWN], valueUpdate);
return ko.utils.extend(allBindings, {valueUpdate: valueUpdate});
}
return allBindings;
};
};
ko.bindingHandlers.value = {
// only needed for init
'init': function (element, valueAccessor, allBindingsAccessor) {
allBindingsAccessor = getInjectValueUpdate(allBindingsAccessor);
return valueHandler.init(element, valueAccessor, allBindingsAccessor);
},
'update': valueHandler.update
};
} ());
「オーバーライド」を快適にしていない場合 value
バインディングでは、オーバーライドカスタムバインディングに別の名前を付けて、そのバインディングハンドラーを使用できます。
ko.bindingHandlers.realtimeValue = { 'init':..., 'update':... };
このようなソリューションは、ノックアウトバージョン2.xに適しています。ノックアウトチームは、テキストのような入力のためにより完全なバインディングを具体化しました TextInput ノックアウトバージョン3以降のバインディング。テキスト入力のすべてのテキスト入力方法を処理するように設計され、 textarea
. 。リアルタイムの更新を処理し、このアプローチを時代遅れにすることを効果的にレンダリングします。
ジェフ・メルカドの答えは素晴らしいですが、残念ながらノックアウト3で壊れています。
しかし、ノックアウト3の変更で作業中にKO開発者によって提案された答えを見つけました。で下のコメントを参照してください https://github.com/knockout/knockout/pull/932. 。彼らのコード:
//automatically add valueUpdate="afterkeydown" on every value binding
(function () {
var getInjectValueUpdate = function (allBindings) {
return {
has: function (bindingKey) {
return (bindingKey == 'valueUpdate') || allBindings.has(bindingKey);
},
get: function (bindingKey) {
var binding = allBindings.get(bindingKey);
if (bindingKey == 'valueUpdate') {
binding = binding ? [].concat(binding, 'afterkeydown') : 'afterkeydown';
}
return binding;
}
};
};
var valueInitHandler = ko.bindingHandlers.value.init;
ko.bindingHandlers.value.init = function (element, valueAccessor, allBindings, viewModel, bindingContext) {
return valueInitHandler(element, valueAccessor, getInjectValueUpdate(allBindings), viewModel, bindingContext);
};
}());
http://jsfiddle.net/mbest/gkjnt/
編集 KO 3.2.0には、新しい「TextInput」バインディングを使用したより完全なソリューションがあります。 Salvidordaliの答えを参照してください