AngularJsの腸には、小さくて素晴らしい機能が1つあります: $ parseです。 通常、フレームワーク内で使用され、値を補間します。たとえば、双方向のデータバインディングの場合などです。
<p>Hello, {{ user.name }}</p> // where user is an object in the scope
この簡単な例は、 ここで明確に見ることができます 。
user.name 式の値を計算するために、AngularJsは$ parseを呼び出し、結果をDOMに入れます。
$ parseは、単にオブジェクトのプロパティを取得するのではなく、 式を変換します。例:
<p>{{ 'Hello ' + user.name }}</p>
ここに例を見ることができます 。
コントローラー(またはその他の関数)に依存関係を追加することで、コードで$ parseを使用できます。 $ parseを呼び出すには、2つのステップが必要です。 式をテンプレート関数にコンパイルしてから、この関数自体をコンテキスト変数とローカル変数で呼び出します。 通常、スコープオブジェクトは$スコープオブジェクトです。
function controller($scope, $parse) { $scope.user = { name: 'Joe' }; var template = $parse('Hello + user.name'); var msg = template($scope); // Hello Joe }
この2ステップの実行は、 Handlebarsなどの他のテンプレートライブラリでも観察されます。
さらに、$ parseは非常に寛容です。たとえば、$ scope.userオブジェクトが存在しない場合、式は通常変換しますが、空の文字列として表示されるundefinedを返します。例を次に示します 。 この$解析関数の動作により、次のハッキングが発生しました。
ハック1:埋め込みプロパティへの安全なアクセス
nullの可能性があるプロパティ値を持つオブジェクトがある場合、このプロパティの添付プロパティにアクセスすると、すべての種類のチェックが強制されます。
var foo = { bar: { baz: { name: 'baz' } } }; var name; if (typeof foo === 'object' && typeof foo.bar === 'object' && typeof foo.bar.baz === 'object') { name = foo.bar.baz.name; }
もちろん、 l33teralなどのサードパーティライブラリを使用して、安全なアクセスのためにオブジェクトをラップできます。
var leet = require('l33teral'); var fooL = leet(foo); var name = fooL.tap('bar.baz.name');
ただし、既にAngularJsを使用している場合は、$ parseを使用します。
var name = $parse('bar.baz.name')(foo);
完全な例 。 プロパティが存在しない場合、呼び出しは未定義を返します。
$parse('bar.baz2.name')(foo); // returns undefined
式の再コンパイルを回避するために、変数の関数に最初のステップを割り当てることもできます。
var getName = $parse('bar.baz.name'); ... getName(foo);
ハック2:バックエンドロジックをクライアントに送信する
クライアントで何かを動的に実行(計算)したい場合は、サーバーからロジックを文字列として送信できます。 メソッドに加えて、ローカル変数を1行で定義できます。この$ parseは2つの引数(コンテキスト変数とローカル変数)で呼び出されます:
var ops = { add: function (a, b) { return a + b; }, mul: function (a, b) { return a * b; } }; var logic = 'mul(add(a, 1), b)'; var data = { a: 10, b: 4 }; var result = $parse(logic)(ops, data); // 44
完全な例 。
データ引数はops引数のコンテキストでプロパティをオーバーライドできますが、実装を理解しやすくするために、メソッドをデータとは別にすることをお勧めします。
ハック3:20分でスプレッドシート
AngularJsの威力を実証するために、 David Graunkeのスプレッドシートの例を参照したいと思います。 これは非常にすばらしく、$ parseを使用して各セル内の式を動的に変換する例です。 式は、他のセルの値を参照でき、そのセルは他のセルなどを参照できます。 この例の主なロジックは、すべてのセルがスコープ内にあり、セルの値が変更されるたびにcoumpute関数が呼び出されることです。
function sheetController($scope, $parse) { $scope.columns = ['A', 'B', 'C', 'D']; $scope.rows = [1, 2, 3, 4]; $scope.cells = {}; // will be filled with row x column objects $scope.compute = function(cell) { return $parse($scope.cells[cell])($scope); }; }
動作中のスプレッドシート 。