
ディレクティブの書き方
Angularjsディレクティブは、次のように他のモジュール構成とともに設定されます。
angular.module('moduleName', []) .directive('directiveName', function () { /*- */ }) .directive('anotherDirectiveName', function () { /*- */ });
発表には2つのオプションがあります。 よりシンプルで強力な長いオプション。
ディレクティブを作成する簡単な方法
HTMLマークアップで指定するときに呼び出されるディレクティブを記述するために、最も単純なケースでは、ファクトリーによって返される関数(Linking Linkingと呼ばれますが、これについては後ほど説明します)を設定する必要があります。
angular.module('moduleName', []) .directive('directiveName', function () { return function(scope,element,attrs){ } });
この関数は、次のパラメーターを受け入れます。
- scope-ディレクティブが呼び出されるスコープ
- element- jQuery Liteでラップされたディレクティブを所有するDOM要素
- attrs-ディレクティブが呼び出されるタグのすべての属性のリストを持つオブジェクト
より詳細な例を使用してみましょう。 このようなディレクティブ( habra-habrを呼び出しましょう)を作成します。このディレクティブは2行を折り畳み、 呼び出されたレイアウト要素内に表示します。 この場合、1行をコントローラー変数( forExampleController )として設定し、2行目を同じタグで属性( habra )を渡します。 また、ディレクティブを呼び出すときにコントローラー変数の名前を決定する機能を予約します。
[ jsFiddle ]
<div ng-app="helloHabrahabr"> <div ng-controller="forExampleController"> <input ng-model="word"> <span habra-habr="word" habra="Nehabra"></span> </div> </div>
function forExampleController($scope) { $scope.word="Habrahabra" } angular.module('helloHabrahabr', []) .directive('habraHabr', function() { return function($scope, element, attrs) { /* , word, attrs.habraHabr*/ $scope.$watch(attrs.habraHabr,function(value){ element.text(value+attrs.habra); }); } });
それだけです プリミティブ形式のディレクティブは準備ができています。 より詳細なフォームに進むことができます。
拡張オプション
完全な形式では、ディレクティブのタスクは次のとおりです。
angular.module('moduleName', []) .directive('directiveName', function () { return { compile: function compile(temaplateElement, templateAttrs) { return { pre: function (scope, element, attrs) { }, post: function(scope, element, attrs) { } } }, link: function (scope, element, attrs) { }, priority: 0, terminal:false, template: '<div></div>', templateUrl: 'template.html', replace: false, transclude: false, restrict: 'A', scope: false, controller: function ($scope, $element, $attrs, $transclude, otherInjectables) { } } });
これらのプロパティはすべて非常に密接に関連しており、絡み合っています。 また、これを理解しやすくするために、特定のセマンティックグループでそれらを考慮することをお勧めします。
リンクとコンパイル
Linkメソッドは、ディレクティブファクトリが短いバージョンで返したまさにその機能です。 ここで、Angularjsではコンパイルプロセスが2つの段階に分かれていることを理解する必要があります。
- コンパイル-このDOM要素で使用されるすべてのディレクティブの分析(子孫を含む)
- リンク-テンプレートで使用される変数とスコープ内の変数のリンク
そして同時に、最も単純なバージョンでも高度なバージョンでも、Linkメソッドは変数が既にマップされた後に実行されるため、 postLinkを正しく呼び出します。 いくつかの例を見てみましょう。
最初に、単純なディレクティブの例を拡張された方法で書き直すことをお勧めします。
[ jsFiddle ]
angular.module('helloHabrahabr', []) .directive('habraHabr', function() { return { link:function($scope, element, attrs) { /* , word*/ $scope.$watch(attrs.habraHabr,function(value){ element.text(value+attrs.habra); } ); } } });
つまり、すべてが以前と同じように機能します。 タスクを複雑にし、フレーズをDOM element.text(...)との直接的な対話ではなく、補間"{{}}"ディレクティブ内に表示できます。
[ jsFiddle ]
angular.module('helloHabrahabr', []) .directive('habraHabrNotwork', function() { return { link:function($scope, element, attrs) { element.html("<div>{{"+attrs.habraHabrWork+"}}"+attrs.habra+"</div>"); } } }) .directive('habraHabrWork', function() { return { compile: function compile(templateElement, templateAttrs) { templateElement.html("<div>{{"+templateAttrs.habraHabrWork+"}}"+templateAttrs.habra+"</div>"); }, link: function (scope, element, attrs) { } } });
上記の例では、 habraHabrNotworkディレクティブは正しく機能しません。これは、ディレクティブ「{{}}」を変数とともにpostLinkに挿入するためです。つまり、コンパイルとリンクが既に完了している場合です。 つまり、Angularjsは、「{{}}」が強制可能なディレクティブであることすら知りません。
もう1つは、2番目のディレクティブです。 すべてが適切な場所にあるので、コンパイルの前にテンプレート "{{" + attrs.habraHabrNotwork + "+" + attrs.habra + "}}"を挿入すると、レンダリングに成功します。
コンパイル方法について詳しく見てみましょう。 postLink関数と、preとpostの2つのパラメーターを持つオブジェクトの両方を返すことができます。 preおよびpostは、それぞれpreLinkおよびpostLinkメソッドです。 メソッドの名前から、 リンク aの前後のメソッドについて話しているように見えるかもしれません。 ただし、これは完全に真実ではありません。これらの機能は、 LinkおよびDOMのchildrenディレクティブの前後に実行されます。 例:
[ jsFiddle ]
<div ng-app="helloHabrahabr"> <div ng-controller="forExampleController"> <input ng-model="word"> <span habra-habr-work="word" habra="NehabraParent"> <span habra-habr-work="word" habra="NehabraChild"></span> </span> <pre>{{log}}</pre> </div> </div>
function forExampleController($scope) { $scope.word="Habrahabra"; $scope.log=""; } angular.module('helloHabrahabr', []) .directive('habraHabrWork', function() { return { compile: function compile(templateElement, templateAttrs) { templateElement.prepend("<div>{{"+templateAttrs.habraHabrWork+"}}"+templateAttrs.habra+"</div>"); return { pre: function ($scope, element, attrs, controller) { $scope.log+=templateAttrs.habra +' preLink \n'; }, post: function ($scope, element, attrs, controller) { $scope.log+=templateAttrs.habra +' postLink \n'; } } } } });
これについては、一時停止することを提案します。 トピックが興味深い場合は、今後数日でスコープとテンプレートについての続編を書きます。