web-dev-qa-db-ja.com

ディレクティブテンプレート内のDOM要素にアクセスするAngularJS

ディレクティブテンプレート内でDOM要素を選択する、より「角度のある」方法はありますか?たとえば、次のディレクティブがあるとします。

app.directive("myDirective", function() {
    return {
        template: '<div><ul><li ng-repeat="item in items"></ul></div>',
        link: function(scope, element, attrs) {
            var list = element.find("ul");
        }
    }
});

JQueryスタイルセレクターを使用して、テンプレートにレンダリングされたDOM <ul>要素を取得しました。これを行うためのより良い方法はありますか?

64
Dustin

このためのディレクティブを記述できます。これは、属性に与えられた名前を使用して、(jqLit​​e)要素をスコープに単純に割り当てます。

ディレクティブは次のとおりです。

app.directive("ngScopeElement", function () {
  var directiveDefinitionObject = {

    restrict: "A",

    compile: function compile(tElement, tAttrs, transclude) {
      return {
          pre: function preLink(scope, iElement, iAttrs, controller) {
            scope[iAttrs.ngScopeElement] = iElement;
          }
        };
    }
  };

  return directiveDefinitionObject;
});

使用法:

app.directive("myDirective", function() {
    return {
        template: '<div><ul ng-scope-element="list"><li ng-repeat="item in items"></ul></div>',
        link: function(scope, element, attrs) {
            scope.list[0] // scope.list is the jqlite element, 
                          // scope.list[0] is the native dom element
        }
    }
});

いくつかのコメント:

  • ネストされたディレクティブのコンパイルとリンクの順序 のため、myDirectives postLink-Functionからのみscope.listにアクセスできます。
  • ngScopeElementはpreLink関数を使用するため、ng-scope-elementを持つ要素内にネストされたディレクティブは既にscope.listにアクセスできます
  • これがパフォーマンスに関してどのように動作するかわからない
40
CodeSalad

要素を選択するためのより「角度のある方法」はないと思います。たとえば、 この古いドキュメントページ の最後の例でこの目標を達成する方法を参照してください。

{
     template: '<div>' +
    '<div class="title">{{title}}</div>' +
    '<div class="body" ng-transclude></div>' +
    '</div>',

    link: function(scope, element, attrs) {
        // Title element
        var title = angular.element(element.children()[0]),
        // ...
    }
}
47
Blackhole

この答えは少し遅れますが、私はちょうど同様のニーズにありました。

質問で@ganarajによって書かれたコメントを見て、私が必要としていた1つのユースケースは、テンプレートのng-repeat liタグに追加されるディレクティブ属性を介してクラス名を渡すことです。

たとえば、次のようなディレクティブを使用します。

<my-directive class2add="special-class" />

そして、次のHTMLを取得します。

<div>
    <ul>
       <li class="special-class">Item 1</li>
       <li class="special-class">Item 2</li>
    </ul>
</div>

here が見つかった解決策は、templateUrlで適用されます。

app.directive("myDirective", function() {
    return {
        template: function(element, attrs){
            return '<div><ul><li ng-repeat="item in items" class="'+attrs.class2add+'"></ul></div>';
        },
        link: function(scope, element, attrs) {
            var list = element.find("ul");
        }
    }
});

AngularJS 1.4.9で試してみました。

それが役に立てば幸い。

5
Gerardo Camacho