2013-04-08 7 views
61

ディレクティブテンプレート内でDOM要素を選択する方法が「角度のある」方法ですか?たとえば、あなたがこのディレクティブを持っていると言う:ディレクティブテンプレート内でDOM要素にアクセスするAngularJS

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"); 
     } 
    } 
}); 

私は私のテンプレートでレンダリングDOM <ul>要素のホールドを取得するjQueryのスタイルセレクタを使用しました。これを行うより良い方法はありますか?

+2

州では、私はそれを行うより良い方法はないと思います。しかし、おそらく要素を選択するよりも良い選択肢があります。あなたの目標は何ですか? – Blackhole

+1

特にありません。これは私が走っている共通の事です。何らかの理由でディレクティブテンプレート内のDOM要素にアクセスする必要がありますが、jQueryスタイルセレクタを使用すると間違っているようです。 – Dustin

+1

@DustinはBlackholeのように、ディレクティブの90%で、セレクタを介してDOM要素にアクセスする必要はありません。これはAngularのJQueryLiteが非常に少数の基本セレクタをサポートする理由ともなっています。あなたが達成しようとしていることを私たちに知らせることができれば、誰かがそれを行うより良い方法を提案するだろう。 – ganaraj

答えて

40

属性、与えられました名。

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 
     } 
    } 
}); 

いくつかの発言:ここ

ディレクティブであるために

  • compile and link order for nested directivesあなただけmyDirectiveのポストリンク-機能からscope.listアクセスすることができ、あなたはとにかく使っている可能性が非常に高いです
  • ngScopeElementng-scope-elementを有する素子内にネストディレクティブはすでにscope.list
  • これは
+2

私はこのアイデアが好きです。かなり洗練されています...パフォーマンスにどのような影響があるのでしょうか。 – Dustin

+4

これはとても優雅なソリューションです。私の現在のプロジェクトでこれを実装するつもりです – Dan

+3

'myDirective'が独自のスコープを宣言している場合、その要素を取得するには' scope。$ parent.list [0] 'を使用する必要があります。 – x1a0

46

要素を選択するための「角度のある角度」があるとは思わない。例えば、彼らはthis old documentation pageの最後の例では、この目標を達成する方法を参照してください。

{ 
    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]), 
     // ... 
    } 
} 
あなたは、単に使用してスコープに(jqLit​​e)要素を割り当て、このためのディレクティブを、書くことができ
+1

これは本当ですが、私はたとえば、同じことを達成するための角度のある方法があります。テンプレートの中に 'ng-click'ディレクティブだけがある' title.bind( 'クリック' ... ')があります。 – Dustin

+0

これは完全に受け入れられる答えです。 –

+0

@DenisLinsまあまあでした。しかし、もう1つの答えは、その重さがある特定の機会に制限されていても、完全に正しい解を提供することです。 – Blackhole

4

この答えは少し遅れていますが、ちょうどI-賢明なパフォーマンスをどのように動作するかわからないにアクセスできるように、prelinkの機能を使用しています同様の必要性がありました。

質問で@ganarajによって書かれたコメントを観察しました。必要だった使用例は、テンプレートのng-repeat liタグに追加されるディレクティブ属性でクラス名を渡したものです。

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

とget次の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で正常に動作しました。

希望します。

関連する問題