[解決済み] AngularJSで双方向のフィルタリングを行うには?
質問
AngularJSでできる面白いことの1つは、特定のデータバインディング式にフィルタを適用することです。これは、例えばモデルのプロパティに文化特有の通貨や日付のフォーマットを適用するのに便利な方法です。また、スコープ上に計算されたプロパティを持つのも良いことです。問題は、これらの機能はどちらも双方向のデータバインディングシナリオで動作しないことです。これは、他の優れたライブラリの目立った欠落であるように思えますが、私は何かを見逃しているのでしょうか?
で KnockoutJS では、読み取り/書き込み可能な計算プロパティを作成することができ、プロパティの値を取得するために呼び出される関数と、プロパティが設定されたときに呼び出される関数のペアを指定することが可能でした。これにより、例えばカルチャーを考慮した入力、つまりユーザーに "$1.24" と入力させ、それを ViewModel の float に解析し、ViewModel の変更が入力に反映されるように実装することができました。
これと似たようなものを見つけることができたのは
$scope.$watch(propertyName, functionOrNGExpression);
のプロパティが指定されたときに呼び出される関数を用意することです。
$scope
のプロパティが変更されたときに呼び出される関数を持つことができます。しかし、これは例えばカルチャを考慮した入力の問題を解決するものではありません。を変更しようとしたときの問題に注目してください。
$watched
プロパティ内で
$watch
メソッド自体の中にあります。
$scope.$watch("property", function (newValue, oldValue) {
$scope.outputMessage = "oldValue: " + oldValue + " newValue: " + newValue;
$scope.property = Globalize.parseFloat(newValue);
});
( http://jsfiddle.net/gyZH8/2/ )
ユーザーが入力を開始すると、input 要素は非常に混乱します。解析されていない値用と解析された値用の2つのプロパティに分割することで改善しました。
$scope.visibleProperty= 0.0;
$scope.hiddenProperty = 0.0;
$scope.$watch("visibleProperty", function (newValue, oldValue) {
$scope.outputMessage = "oldValue: " + oldValue + " newValue: " + newValue;
$scope.hiddenProperty = Globalize.parseFloat(newValue);
});
( http://jsfiddle.net/XkPNv/1/ )
これは最初のバージョンより改善されましたが、少し冗長になり、また、まだ
parsedValue
プロパティが変更されることに注意してください (2 番目の入力で何かを入力すると、その入力によって
parsedValue
を直接変更します。一番上の入力は更新されないことに注意してください)。これは、コントローラのアクションやデータサービスからのデータの読み込みによって発生する可能性があります。
AngularJSを使用してこのシナリオを実装するための簡単な方法はありますか?ドキュメントにある機能を見逃しているのでしょうか?
どのように解決するのですか?
これには非常にエレガントな解決策があることがわかりましたが、あまり文書化されていません。
表示するためのモデルの値のフォーマットは
|
演算子と、角のある
formatter
. フォーマッタのリストだけでなく、パーサーのリストも持っている ngModel があることがわかります。
1. 使用方法
ng-model
を使用して、双方向のデータバインディングを作成します。
<input type="text" ng-model="foo.bar"></input>
2. 同じ要素に適用されるディレクティブをangularモジュールに作成し、そのディレクティブは
ngModel
コントローラ
module.directive('lowercase', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, element, attr, ngModel) {
...
}
};
});
3. の中で
link
メソッド内で、カスタムコンバータを
ngModel
コントローラに追加します。
function fromUser(text) {
return (text || '').toUpperCase();
}
function toUser(text) {
return (text || '').toLowerCase();
}
ngModel.$parsers.push(fromUser);
ngModel.$formatters.push(toUser);
4. 新しいディレクティブを、すでに存在する
ngModel
<input type="text" lowercase ng-model="foo.bar"></input>
ここでは
の動作例です。
の中でテキストを小文字に変換しています。
input
で小文字に変換し、モデルで大文字に戻しています。
は モデルコントローラの API ドキュメント にも、簡単な説明とその他の利用可能なメソッドの概要があります。
関連
-
[解決済み] 配列から特定の項目を削除するにはどうすればよいですか?
-
[解決済み] jQueryで要素が非表示になっているかどうかを確認するには?
-
[解決済み] JavaScriptで文字列が部分文字列を含むかどうかを確認する方法は?
-
[解決済み] JavaScriptでメールアドレスを検証するのに最適な方法は何ですか?
-
[解決済み] JavaScriptでオブジェクトをディープクローンする最も効率的な方法は何ですか?
-
[解決済み] AngularJSでデータバインディングはどのように機能するのですか?
-
[解決済み】別のウェブページにリダイレクトするにはどうすればいいですか?
-
[解決済み] ExtJS 4のイベントハンドリングについて
-
[解決済み] react-routerのハッシュフラグメントからクエリパラメータを取得する
-
[解決済み] Chrome拡張機能:popup.htmlを強制終了させる
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] 文字列のn番目の出現箇所を取得するには?
-
[解決済み] javascript includes() 大文字小文字を区別しない
-
[解決済み] moment.jsでミュータビリティを回避するには?
-
[解決済み] AngularJS - ngRepeatフィルタリングされた結果の参照を取得する方法
-
[解決済み] javascriptで文字列から関数を作成する方法はありますか?
-
[解決済み] jQueryで入力ファイルが空かどうかをチェックする方法
-
[解決済み] JavaScriptで長い配列を小さい配列に分割する方法
-
[解決済み] Javascript の parseInt() で先頭のゼロを削除する。
-
[解決済み] JavaScriptのArray.sort()メソッドでシャッフルするのは正しいのか?
-
[解決済み] これは純関数ですか?