AngularJS を使用する場合、ディレクティブ内で DOM 要素を操作する必要があることはよく知られています。
ただし、一部のユース ケースでは、サービス内で DOM を操作することが許容されるようです。Misko Hevery はこれについてここで話しています。Bootstrap UI Dialog内にも例があります。
Misko の説明はかなり曖昧なので、ディレクティブではなくサービス内に DOM を配置する必要がある場合をどのように判断するのだろうかと思っていました。
AngularJS を使用する場合、ディレクティブ内で DOM 要素を操作する必要があることはよく知られています。
ただし、一部のユース ケースでは、サービス内で DOM を操作することが許容されるようです。Misko Hevery はこれについてここで話しています。Bootstrap UI Dialog内にも例があります。
Misko の説明はかなり曖昧なので、ディレクティブではなくサービス内に DOM を配置する必要がある場合をどのように判断するのだろうかと思っていました。
ディレクティブは、その定義方法に従って、常に DOM ノードに関連付けられます。したがって、ディレクティブを定義すると、ディレクティブが関連付けられている DOM ノードを「展開」または置換します。
特定の状況 (ダイアログなど) では、特定の親に DOM ノードをアタッチできません。このような場合、サービスを使用することは理にかなっており、DOM 操作はサービスにカプセル化されるため、コントローラーは引き続き DOM ビットから離れることができます。
ポップアップは、おそらくサービスを使用できる別の状況である可能性がありますが、ダイアログとは異なり、ポップアップは DOM ノードに関連付けられています。ですから、それも少しグレーゾーンです。
したがって、基本的で単純なテストは、「この DOM 操作コードを DOM ノードに接続できるか?」です。はいの場合は、ディレクティブ。いいえの場合は、サービス。
ダイアログとカスタム確認ボックスは、サービスを使用する典型的な例です。
Ganaraj は Misko が言ったことをうまく説明していると思いますが、モーダル ダイアログの DOM 操作コード (たとえば)をDOM ノードに入れることができると主張することができます (またそうすべきかもしれません)。
1 つの方法は、ダイアログ ディレクティブを常に DOM にアタッチし、それng-show
を条件付きで表示するために使用することです。その後、サービスを使用してモーダル ダイアログと通信でき$rootScope
ます。
「正しい」と感じるので、私は実際にこのアプローチを好みます。サービスはデータの転送を処理し、ディレクティブはサービスとやり取りして、ユーザーにとって意味のある方法で表示されるようにします。
しかし、ミスコがそれについて特に明確ではないという事実は、それがかなり主観的であることを示していると思います. あなたにとって最も意味のあることをしてください。
サービスに特定のロジックを配置したいという問題に現在取り組んでいるため、このトピックをグーグルで検索して、これについての私の内なる感情を強化しています。これが私のケースであり、DOM ベースの処理をサービスに導入する十分な正当性があると思います。
マウスの位置にグローバルに反応するディレクティブベースの要素があります (たとえば、マウスの位置に基づいて何らかの方法で移動または変更します)。これらの要素の数は不確定であり、アプリケーション内の特定の場所には関係しません (これは GUI 要素であり、どこにあるコンテナにも関係する可能性があるためです)。厳密な角度の「ディレクティブのみの dom ロジック」ルールに従うと、window.requestAnimationFrame ティックを中心に展開するマウス位置の解析に関連するロジックをすべての要素が (効率的に) 共有するため、効率が低下します。
そのロジックをディレクティブにバンドルすると、リスナー/raf ループがすべてのインスタンスに関連付けられます。これはまだ DRY ですが、マウスを動かすたびにまったく同じリスナーが起動され、すべての要素に対してまったく同じ結果が返されるため、効率的ではありません。
この場合、DOM ベースのロジックであるにもかかわらず、これをサービスに移動し、各ディレクティブ インスタンスをサービスに対して登録して、実行されるロジックに対して同じインスタンス ベースのロジックを呼び出し、インスタンスごとに複製することをお勧めします。
Angular はコードをどのように構築するかについていくつかの非常に優れたアドバイスを提供しますが、すべてのユース ケースをカバーできるわけではないため、絶対に厳格で迅速なルールを保証するものではありません。「ベスト プラクティス」が失敗しているように見える穴がある場合、それは実際にベスト プラクティスを適切に理解しているためであり、故意にルールを破る理由を見つけたからです。
それはちょうど私の 2 セントです !
変数 (つまり ) の変更に基づく DOM 操作メソッドを使用する場合の欠点の 1 つng-show="isVisible"
は、DOM 操作が次の「JavaScript ターン」ループ (isVisible
が更新されたとき) の後で発生することです。DOM をすぐに更新する必要がある場合があります。
たとえば、一般的なシナリオは、新しいルート/状態への遷移中に「スピナー」を表示することです。/イベントを設定$scope.isVisible = true
してから/$routeChangeStart
イベント$stateChangeStart
を設定した場合、ルート / 状態全体の変更が 1 つの JavaScript ターン内で発生するため、 が表示されることはありません。実際にスピナーを表示するには、これらのイベントでandを使用することをお勧めします。$scope.isVisible = false
$routeChangeSuccess
$stateChangeSuccess
ng-show
.show()
.hide()
これをすべて元に戻し、OPの質問に関連させるために-DOM操作が表示されている「スピナー」モーダルである状況では、サービス中にそれを行い、直接DOM操作メソッドで行います。モデルチェンジに頼るのではなく。