web-dev-qa-db-ja.com

Angular 1.5コンポーネントと古いディレクティブ-リンク関数はどこにありますか?

私はこの素敵な最近の記事を読んでいます 記事 Angular 1.5の新しい.component()ヘルパーは、誰もがAngularに移行するのに役立つはずです2最終的に。すべてが素晴らしくシンプルに見えますが、コンポーネント内のDOM操作に関する情報を見つけることができませんでした。

ただし、templateプロパティがあり、これは関数であり、$elementおよび$attrs引数を受け入れることができます。それでも、それがlink関数の代替であるかどうかは明確ではありません。そうではないようです。

58
troorl

EDIT 2/2/16:1.5のドキュメントは、コンポーネントをカバーするようになりました: https://docs.angularjs.org/guide/component


いくつかの読書に基づいていくつかの考え(以下のリンク):

  • コンポーネントはディレクティブの代わりではありません。コンポーネントは、テンプレートを使用してコントローラーを編成する特別なタイプのディレクティブです。

  • コンポーネントにはリンク機能がなく、コントローラーはまだDOM操作を処理する場所ではありません。

  • DOM操作が必要な場合、コンポーネントはリンク関数にそのDOM操作を含む他のディレクティブを使用できます。

これを理解するのにしばらく時間がかかりましたが、一度理解すると、コンポーネントはディレクティブですが、すべてのディレクティブがコンポーネントである必要はありません。

リンク関数に関する質問は、コンポーネントがディレクティブを置き換えていると思ったときに自然な質問でした。どうして?ディレクティブのリンク関数内にDOM操作を配置するように教えられているため、「DOMを変更するディレクティブは通常、リンクオプションを使用してDOMリスナーを登録し、DOMを更新します。」 https://docs.angularjs.org/guide/directive

その前提で実行している場合(コンポーネントがディレクティブに置き換わる)、Angularドキュメントは質問に答えないことがわかります。なぜなら、目的を知った後は正しい質問ではないからです。コンポーネント。 (コンポーネントは $ compileProviderドキュメント ではなく、 ディレクティブドキュメント では説明されていません。)

バックグラウンドリーディング

上記で私が言ったことは、トッド・モットが言った、コンポーネントとディレクティブに関する(これまでの)おそらく最高の議論の内容の言い換えです。

https://www.reddit.com/r/angularjs/comments/3taxjq/angular_15_is_set_to_introduce_the_component/

これらのコメントをより一般的な記事にまとめておくと便利です。

コンポーネントに関するほとんどの記事では、リンク機能について言及していません(これが優れた記事ではないという意味ではありません)。

https://toddmotto.com/exploring-the-angular-1-5-component-method/

https://medium.com/@tomastrajan/component-paradigm-cf32e94ba78b#.vrbo1xso

https://www.airpair.com/angularjs/posts/component-based-angularjs-directives

または、リンク関数が記載されている場合は、括弧で囲まれています。

http://teropa.info/blog/2015/10/18/refactoring-angular-apps-to-components.html

1つの記事 は、「リンク関数の代わりにコントローラーを使用する」というコンポーネントです。しかし、それは「代わりの」状況ではありません。コントローラーはリンク機能の代役ではありません。

72
jody tate

これにより、Webコンポーネントを使用したり、Angular 2のスタイルのアプリケーションアーキテクチャを使用したりするのと同様の方法で、アプリを簡単に作成できます。

コンポーネントの利点:

プレーンなディレクティブよりも構成が単純であるため、コンポーネントディレクティブを記述するコンポーネントベースのアーキテクチャに最適化された適切なデフォルトとベストプラクティスが促進され、Angular 2へのアップグレードが容易になります。

コンポーネントを使用しない場合:

dOM操作、イベントリスナーの追加などに依存するディレクティブの場合、優先度、ターミナル、マルチエレメントなどの高度なディレクティブ定義オプションが必要な場合、属性またはCSSクラスによってトリガーされるディレクティブが必要な場合、コンパイルおよびリンク機能が使用できないため、要素ではなく

7
surekha shelake

更新(2017年8月22日から):これをAngularJSで行うには、$ injectをお勧めします。スタイルガイドを読む: スタイルガイドリンク およびAngularJSドキュメント: AngularJSドキュメント

リンク関数でディレクティブを作成する代わりに、コンポーネントでDOMバインディングを使用するには、「$ element」またはコントローラー関数で必要な他のサービスを注入できます。

app.component('pickerField', {
    controller: PickerField,
    template: '<span>Your template goes here</span>'
  });

  PickerField.$inject = ['$element'];

  function PickerField(element) {
    var self = this;
    self.model = self.node.model;
    self.open = function() {
      console.log('smth happens here');
    };
    element.bind('click', function(e) {
      console.log('clicked from component', e);
      self.open();
    });
  }
4

わかりましたので、それが唯一の可能なものであるため、コントローラは今それのための正しい場所であるように見えます。また、コンポーネントヘルパーでreplaceオプションを使用することはできません。

2
troorl

最新の角度の$ postLink()関数を使用できます。

https://docs.angularjs.org/guide/component

リンク後関数と同様に、このフックを使用してDOMイベントハンドラーをセットアップし、直接DOM操作を行うことができます。

0
Szymon