AngularJS対jQuery
AngularJSとjQueryは非常に異なるイデオロギーを採用しています。jQueryを使用している場合は、驚くべき違いが見つかることがあります。Angularはあなたを怒らせるかもしれません。
これは正常な状態です。プッシュする必要があります。Angularはそれだけの価値があります。
大きな違い(TLDR)
jQueryは、DOMの任意のビットを選択し、それらにアドホックな変更を加えるためのツールキットを提供します。好きなことはほとんど何でもできます。
AngularJSは代わりにコンパイラを提供します。
つまり、AngularJSはDOM全体を上から下に読み取り、それをコードとして、文字通りコンパイラーへの指示として扱います。DOMを通過するときに、特定のディレクティブを探します、AngularJSコンパイラーに動作方法と実行方法を指示(コンパイラーディレクティブ)をます。ディレクティブはJavaScriptでいっぱいの小さなオブジェクトで、属性、タグ、クラス、さらにはコメントと照合できます。
Angularコンパイラは、DOMの一部が特定のディレクティブと一致すると判断すると、ディレクティブ関数を呼び出し、DOM要素、属性、現在の$ scope(ローカル変数ストア)、およびその他の有用なビットを渡します。これらの属性には、ディレクティブで解釈できる式を含めることができます。この式は、レンダリングの方法と、いつ再描画するかを指示します。
次に、ディレクティブはコントローラー、サービスなどの追加のAngularコンポーネントを取り込むことができます。コンパイラーの下部に表示されるのは、完全に形成されたWebアプリケーションであり、配線されてすぐに使用できます。
これは、Angularがテンプレート駆動であることを意味します。テンプレートはJavaScriptを駆動しますが、その逆ではありません。これは役割が根本的に逆転したものであり、過去10年間ほど私たちが書いてきた控えめなJavaScriptとは正反対です。これには慣れるまでに時間がかかる場合があります。
これが過度に規範的で制限的であるように聞こえる場合は、真実から遠く離れているものはありません。AngularJSはHTMLをコードとして扱うため、WebアプリケーションでHTMLレベルの細分性が得られます。すべてが可能であり、いくつかの概念的な飛躍をすれば、ほとんどのことは驚くほど簡単です。
要点に取り掛かりましょう。
まず、AngularはjQueryを置き換えません
AngularとjQueryは異なる動作をします。AngularJSは、Webアプリケーションを作成するための一連のツールを提供します。jQueryは主にDOMを変更するためのツールを提供します。ページにjQueryが存在する場合、AngularJSはそれを自動的に使用します。そうでない場合、AngularJSにはjQuery Liteが同梱されています。これは削減されていますが、jQueryの完全に使用可能なバージョンです。
MiskoはjQueryが好きで、jQueryの使用に反対しません。ただし、進むにつれて、スコープ、テンプレート、およびディレクティブの組み合わせを使用してほぼすべての作業を実行できることがわかります。コードはより離散的で構成可能であり、さらに多くのことができるため、可能な限りこのワークフローを優先する必要があります。角度。
jQueryを使用する場合、それをあちこちに散らばってはいけません。AngularJSでのDOM操作の正しい場所はディレクティブです。これらについては後で詳しく説明します。
セレクター付きの控えめなJavaScriptと宣言型テンプレート
jQueryは通常、控えめに適用されます。JavaScriptコードはヘッダー(またはフッター)でリンクされており、ここに記載されているのはここだけです。セレクターを使用してページの一部を選択し、それらの部分を変更するプラグインを作成します。
JavaScriptが制御しています。HTMLは完全に独立した存在です。JavaScriptがなくても、HTMLはセマンティックのままです。Onclick属性は非常に悪い習慣です。
AngularJSについて最初に気づくのは、カスタム属性がどこにでもあるということです。HTMLはng属性で散らかされます。これらは本質的にステロイドのonClick属性です。これらはディレクティブ(コンパイラディレクティブ)であり、テンプレートをモデルにフックする主な方法の1つです。
これを初めて目にしたとき、AngularJSを(私が最初にしたように)古い学校の邪魔なJavaScriptとして書きたくなるかもしれません。実際、AngularJSはこれらのルールに従っていません。AngularJSでは、HTML5はテンプレートです。AngularJSによってコンパイルされ、Webページが生成されます。
これが最初の大きな違いです。jQueryにとって、あなたのWebページは操作されるDOMです。AngularJSにとって、HTMLはコンパイルされるコードです。AngularJSはWebページ全体を読み取り、組み込みコンパイラを使用して文字通りそれを新しいWebページにコンパイルします。
テンプレートは宣言型である必要があります。それを読むだけでその意味が明確になるはずです。わかりやすい名前のカスタム属性を使用します。ここでも、意味のある名前で新しいHTML要素を作成します。最小限のHTML知識を持ち、コーディングスキルがないデザイナーは、AngularJSテンプレートを読んで、それが何をしているかを理解できます。彼または彼女は変更を加えることができます。これがAngularの方法です。
テンプレートは運転席にあります。
AngularJSを起動してチュートリアルを実行するときに私が最初に尋ねた質問の1つは、「コードはどこにありますか?」です。。私はJavaScriptを作成していませんが、それでもこのような振る舞いをしています。答えは明白です。AngularJSはDOMをコンパイルするため、AngularJSはHTMLをコードとして扱います。多くの単純なケースでは、多くの場合、テンプレートを作成して、AngularJSにそれをアプリケーションにコンパイルさせるだけで十分です。
テンプレートがアプリケーションを動かします。DSLとして扱われます。AngularJSコンポーネントを作成すると、AngularJSがコンポーネントを取り込んで、テンプレートの構造に基づいて適切なタイミングで使用できるようにします。これは、テンプレートが出力専用である標準のMVCパターンとは大きく異なります。
たとえばRuby on RailsよりもXSLTに似ています。
これは、慣れが必要な制御の根本的な逆転です。
JavaScriptからアプリケーションを駆動しようとするのをやめます。テンプレートでアプリケーションを駆動し、AngularJSでコンポーネントの相互接続を処理します。これもまた角度的な方法です。
セマンティックHTMLとセマンティックモデル
jQueryでは、HTMLページに意味のある意味のあるコンテンツを含める必要があります。JavaScriptが(ユーザーまたは検索エンジンによって)オフにされている場合、コンテンツは引き続きアクセス可能です。
AngularJSはHTMLページをテンプレートとして扱うからです。コンテンツは通常、最終的にAPIから取得されるモデルに格納されるため、テンプレートはセマンティックである必要はありません。AngularJSは、モデルを使用してDOMをコンパイルし、セマンティックWebページを生成します。
HTMLソースはセマンティックではなくなり、代わりにAPIとコンパイルされたDOMはセマンティックになります。
AngularJSでは、モデルに存在することを意味し、HTMLは単なるテンプレートであり、表示専用です。
この時点で、SEOとアクセシビリティに関してあらゆる種類の質問がありそうです。ここには未解決の問題があります。ほとんどのスクリーンリーダーがJavaScriptを解析するようになります。検索エンジンはAJAX処理されたコンテンツをインデックスに登録することもできます。それでも、pushstate URLを使用していて、適切なサイトマップがあることを確認する必要があります。この問題の説明については、こちらをご覧ください:https : //stackoverflow.com/a/23245379/687677
懸念の分離(SOC)とMVC
懸念の分離(SOC)は、SEO、アクセシビリティ、ブラウザの非互換性など、さまざまな理由で長年のWeb開発で成長してきたパターンです。次のようになります。
- HTML-セマンティックな意味。HTMLは独立している必要があります。
- CSS-スタイリング。CSSがなくてもページは読み取り可能です。
- JavaScript-動作、スクリプトなしではコンテンツは残ります。
繰り返しになりますが、AngularJSは彼らのルールに従っていません。脳卒中では、AngularJSは、受け取った知恵の十年を廃止し、代わりにテンプレートがもはやない少しでも、セマンティックであるMVCパターンを実装します。
次のようになります。
- モデル-モデルにはセマンティックデータが含まれています。モデルは通常JSONオブジェクトです。モデルは$ scopeと呼ばれるオブジェクトの属性として存在します。テンプレートがアクセスできる$ scopeに便利なユーティリティ関数を保存することもできます。
- ビュー-ビューはHTMLで記述されています。データはモデルに存在するため、ビューは通常セマンティックではありません。
- コントローラ-コントローラは、ビューをモデルにフックするJavaScript関数です。その機能は$ scopeを初期化することです。アプリケーションによっては、コントローラーを作成する必要がある場合とない場合があります。1つのページに多くのコントローラーを含めることができます。
MVCとSOCは同じスケールの反対側ではなく、完全に異なる軸上にあります。AngularJSのコンテキストではSOCは意味がありません。それを忘れて先に進む必要があります。
私のように、ブラウザ戦争を生き抜いたとしたら、この考えはかなり不快なものになるかもしれません。それを乗り越えて、それはそれの価値があるでしょう、私は約束します。
プラグインとディレクティブ
プラグインはjQueryを拡張します。AngularJSディレクティブは、ブラウザーの機能を拡張します。
jQueryでは、jQuery.prototypeに関数を追加してプラグインを定義します。次に、要素を選択して結果のプラグインを呼び出すことにより、これらをDOMにフックします。そのアイデアは、jQueryの機能を拡張することです。
たとえば、ページにカルーセルが必要な場合は、おそらくnav要素にラップされた、番号なしの図のリストを定義できます。次に、jQueryを記述してページ上のリストを選択し、スライディングアニメーションを実行するためのタイムアウト付きのギャラリーとして再スタイルします。
AngularJSでは、ディレクティブを定義します。ディレクティブは、JSONオブジェクトを返す関数です。このオブジェクトは、AngularJSに、検索するDOM要素と、それらに加える変更を指示します。ディレクティブは、ユーザーが考案した属性または要素を使用してテンプレートにフックされます。新しい属性と要素でHTMLの機能を拡張するという考え方です。
AngularJSの方法は、ネイティブに見えるHTMLの機能を拡張することです。HTMLのように見え、カスタム属性と要素で拡張されたHTMLを記述する必要があります。
カルーセルが必要な場合は、<carousel />
要素を使用して、テンプレートを取り込むディレクティブを定義し、その吸盤を機能させます。
多くの小さなディレクティブと、設定スイッチ付きの大きなプラグイン
jQueryの傾向は、ライトボックスのような大きなプラグインを作成して、多数の値とオプションを渡して構成することです。
これはAngularJSの誤りです。
ドロップダウンの例を見てみましょう。ドロップダウンプラグインを作成するとき、クリックハンドラーでコードを作成したくなるかもしれません。おそらく、シェブロンを上または下に追加する関数、おそらく展開された要素のクラスを変更する、メニューを非表示にする、すべての役立つものです。
あなたが小さな変更をしたいまで。
ホバー時に展開したいメニューがあるとします。さて、私たちは問題を抱えています。プラグインはクリックハンドラーに接続されています。この特定のケースで動作が異なるようにするには、構成オプションを追加する必要があります。
AngularJSでは、より小さなディレクティブを記述します。私たちのドロップダウンディレクティブは途方もなく小さいでしょう。折りたたみ状態を維持し、fold()、unfold()、またはtoggle()のメソッドを提供する場合があります。これらのメソッドは、状態を保持するブール値である$ scope.menu.visibleを更新するだけです。
これで、テンプレートでこれを接続できます。
<a ng-click="toggle()">Menu</a>
<ul ng-show="menu.visible">
...
</ul>
マウスオーバーで更新する必要がありますか?
<a ng-mouseenter="unfold()" ng-mouseleave="fold()">Menu</a>
<ul ng-show="menu.visible">
...
</ul>
テンプレートがアプリケーションを駆動するため、HTMLレベルの細分性が得られます。ケースバイケースの例外を作りたい場合、テンプレートはこれを簡単にします。
クロージャーと$ scope
jQueryプラグインはクロージャー内に作成されます。プライバシーはその閉鎖内で維持されます。そのクロージャ内でスコープチェーンを維持するのはあなた次第です。実際にアクセスできるのは、jQueryによってプラグインに渡されたDOMノードのセットに加えて、クロージャーで定義されたローカル変数と定義したグローバルのみです。つまり、プラグインは完全に自己完結型です。これは良いことですが、アプリケーション全体を作成するときに制限が生じる可能性があります。動的ページのセクション間でデータを受け渡すことは、面倒な作業になります。
AngularJSには$ scopeオブジェクトがあります。これらは、モデルを保存するAngularJSによって作成および維持される特別なオブジェクトです。特定のディレクティブは、新しい$ scopeを生成します。これは、デフォルトでは、JavaScriptプロトタイプの継承を使用して、そのラッピング$ scopeから継承します。$ scopeオブジェクトには、コントローラーとビューからアクセスできます。
これは賢い部分です。$ scope継承の構造はDOMの構造にほぼ準拠しているため、要素は独自のスコープとそれに含まれるスコープに、グローバル$ scope(グローバルスコープとは異なります)までシームレスにアクセスできます。
これにより、データを渡しやすくなり、適切なレベルでデータを保存できるようになります。ドロップダウンが展開されている場合、それについて知る必要があるのはドロップダウン$ scopeだけです。ユーザーが設定を更新する場合、グローバル$ scopeを更新することができ、ユーザー設定をリッスンしているネストされたスコープには自動的にアラートが送信されます。
これは複雑に聞こえるかもしれませんが、実際にリラックスすると、まるで飛行のようになります。$ scopeオブジェクトを作成する必要はありません。AngularJSは、テンプレート階層に基づいて、適切かつ適切にインスタンス化および構成します。次に、AngularJSは、依存性注入の魔法を使用してコンポーネントで使用できるようにします(これについては後で詳しく説明します)。
手動DOMの変更とデータバインディング
jQueryでは、すべてのDOM変更を手動で行います。プログラムで新しいDOM要素を作成します。JSON配列があり、それをDOMに配置する場合は、HTMLを生成して挿入する関数を記述する必要があります。
AngularJSでもこれを行うことができますが、データバインディングを利用することをお勧めします。モデルを変更します。DOMはテンプレートを介してモデルにバインドされるため、DOMは自動的に更新されるため、介入は必要ありません。
データバインディングはテンプレートから、属性または中かっこ構文を使用して行われるため、非常に簡単です。それに関連付けられている認知のオーバーヘッドがほとんどないので、あなたはいつもそれをやっていることに気付くでしょう。
<input ng-model="user.name" />
入力要素をにバインドします$scope.user.name
。入力を更新すると、現在のスコープの値が更新され、その逆も同様です。
同様に:
<p>
{{user.name}}
</p>
ユーザー名を段落に出力します。これはライブバインディングなので、$scope.user.name
値が更新されると、テンプレートも更新されます。
いつもアヤックス
jQueryでは、Ajax呼び出しを行うのはかなり簡単ですが、それでも、よく考えてしまうかもしれません。考慮すべき追加の複雑さ、および維持すべきスクリプトのかなりのチャンクがあります。
AngularJSでは、Ajaxがデフォルトの主要ソリューションであり、ほとんど気付かれることなく、常に発生します。ng-includeを使用してテンプレートを含めることができます。最も単純なカスタムディレクティブを使用してテンプレートを適用できます。Ajax呼び出しをサービスにラップして、GitHubサービス、または驚くほど簡単にアクセスできるFlickrサービスを自分で作成できます。
サービスオブジェクトとヘルパー関数
jQueryでは、APIからのフィードのプルなど、domに関連しない小さなタスクを実行したい場合、クロージャーでそれを行うための小さな関数を作成する場合があります。これは有効な解決策ですが、そのフィードに頻繁にアクセスしたい場合はどうでしょうか。そのコードを別のアプリケーションで再利用したい場合はどうなりますか?
AngularJSはサービスオブジェクトを提供します。
サービスは、関数とデータを含む単純なオブジェクトです。それらは常にシングルトンです。つまり、それらが複数になることはありません。Stack Overflow APIにアクセスしたいとしますStackOverflowService
。そのためのメソッドを定義するを作成します。
ショッピングカートがあるとします。カートを維持し、アイテムを追加および削除するためのメソッドを含むShoppingCartServiceを定義する場合があります。サービスはシングルトンであり、他のすべてのコンポーネントによって共有されるため、ショッピングカートに書き込み、そこからデータをプルする必要があるオブジェクト。それは常に同じカートです。
サービスオブジェクトは自己完結型のAngularJSコンポーネントであり、必要に応じて使用および再利用できます。これらは、関数とデータを含む単純なJSONオブジェクトです。これらは常にシングルトンであるため、1つの場所のサービスにデータを格納すると、同じサービスを要求するだけで、そのデータを別の場所に取り出すことができます。
依存性注入(DI)とインスタシエーション-別名スパゲティフィケーション
AngularJSが依存関係を管理します。オブジェクトが必要な場合は、それを参照するだけで、AngularJSが取得します。
あなたがこれを使い始めるまで、これがどれほどの大規模な恩恵であるかを説明するのは難しいです。AngularJS DIのようなものはjQuery内には存在しません。
DIは、アプリケーションを作成して一緒に配線するのではなく、それぞれが文字列で識別されるコンポーネントのライブラリを定義することを意味します。
たとえば、FlickrからJSONフィードをプルするためのメソッドを定義する「FlickrService」というコンポーネントがあるとします。ここで、Flickrにアクセスできるコントローラーを作成する場合は、コントローラーを宣言するときに、名前で「FlickrService」を参照するだけで済みます。AngularJSはコンポーネントをインスタンス化し、コントローラーで利用できるようにします。
たとえば、ここでサービスを定義します。
myApp.service('FlickrService', function() {
return {
getFeed: function() { // do something here }
}
});
このサービスを使用したい場合は、次のように名前で参照します。
myApp.controller('myController', ['FlickrService', function(FlickrService) {
FlickrService.getFeed()
}]);
AngularJSは、コントローラーをインスタンス化するためにFlickrServiceオブジェクトが必要であることを認識し、それを提供します。
これにより、配線が非常に簡単になり、スパゲティ化の傾向がほとんどなくなります。コンポーネントのフラットリストがあり、AngularJSは必要に応じて1つずつコンポーネントを渡します。
モジュラーサービスアーキテクチャ
jQueryは、コードをどのように編成する必要があるかについてほとんど言及していません。AngularJSには意見があります。
AngularJSは、コードを配置できるモジュールを提供します。たとえば、Flickrと通信するスクリプトを作成している場合は、Flickrモジュールを作成して、Flickr関連のすべての関数をラップすることができます。モジュールには他のモジュール(DI)を含めることができます。通常、メインアプリケーションはモジュールです。これには、アプリケーションが依存する他のすべてのモジュールが含まれます。
簡単なコードの再利用が可能です。Flickrに基づいて別のアプリケーションを作成したい場合は、Flickrモジュールと出来上がりを含めるだけで、新しいアプリケーションのすべてのFlickr関連機能にアクセスできます。
モジュールにはAngularJSコンポーネントが含まれています。モジュールを含めると、そのモジュール内のすべてのコンポーネントが、一意の文字列で識別される単純なリストとして使用できるようになります。次に、AngularJSの依存性注入メカニズムを使用して、これらのコンポーネントを相互に注入できます。
総括する
AngularJSとjQueryは敵ではありません。AngularJS内でjQueryを非常にうまく使用できます。AngularJSをうまく使用している場合(テンプレート、データバインディング、$ scope、ディレクティブなど)、必要なjQueryよりもはるかに少ないjQuery が必要であることがわかります。
理解すべき主なことは、テンプレートがアプリケーションを駆動することです。すべてを実行する大きなプラグインの作成をやめます。代わりに、1つのことを行う小さなディレクティブを記述してから、それらを結び付ける単純なテンプレートを記述します。
控えめなJavaScriptについては考えずに、HTML拡張機能の観点から考えてください。
私の小さな本
私はAngularJSにとても興奮しました。オンラインでhttp://nicholasjohnson.com/angular-book/を読んで、大歓迎です。お役に立てれば幸いです。