50

Angularチュートリアルを読んでいると、とても気に入っていますが、「ng-click」はインラインonClickに相当しませんか?私の理解では、JavaScriptコミュニティは、HTML内のインラインJavaScriptイベントハンドラーは「悪い習慣」であると判断しました。

<img ng-src="{{img}}" ng-click="setImage(img)">

Angularを使用するときに、これが「正しくない」と見なされなくなった理由を知ることは素晴らしいことです。

ソース:http ://docs.angularjs.org/tutorial/step_10

4

1 に答える 1

59

実際、それはすべて、ビューコードを何らかの方法でアプリケーションロジックにフックする必要があるという事実に帰着します。AngularJSのベストプラクティスでは、通常、独自のモデル(ビジネスドメインを表すオブジェクト)を作成し、それらをスコープにアタッチする必要があると述べています。次のようなコードを想像してみてください。

<img ng-src="{{img}}" ng-click="myProfile.setMainImage(img)">
myApp.controller("ProfileController", function($scope, myProfile) {
  $scope.myProfile = myProfile;
});

ビューには、「この画像をクリックすると、myProfileでsetMainImage()が呼び出されます」と表示されます。ビジネスロジックは内部myProfileにあり、テストなどが可能です。ビューは単なるフックです。

より「従来の」または「バニラ」のjQueryセットアップでは、次のように記述する必要があります。

$("#someId img").on('click', function() {
  var img = $(this).attr('src');
  myProfile.setMainImage(img); // where does myProfile come from here?
                               // how does it update the view?
});

もちろん、JavaScriptコミュニティは、ビューとモデルオブジェクト(コードスニペットのコメントで示されている)が切断されていることもあり、この方法で大規模なアプリケーションを作成することは実際には困難であると判断しています。そもそもAngularのようなフレームワークがあります。

したがって、このネイティブjQueryコードは理想的ではないことはわかっていますが、全体についてはまだわかりませんngClick。それを、MV*アーキテクチャを提供する別の非常に人気のあるJavaScriptフレームワークであるBackboneと比較してみましょう。AngularJSに関する最近のRailsCastsのエピソードで、誰かが非常によく似た質問をしました

それは私だけですか、それともAngularJSはとても悪い考えに見えますか?ライアン、誤解しないでください。エピソードは素晴らしかったですが、フレームワークには納得できません。

これらはすべてng-show、古いJavaのJSFや同様のフレームワークのように見えますng-repeatng-classまた、とを使用して目障りなJSを適用ng-submitng-clickます。

だから私のポイントは、あなたの見方は簡単に散らかってしまい、完全にそれに依存するようになるということです。Backboneのような他のフレームワークの利点は、プレゼンテーションと動作(依存関係が少ないかまったくない)と、構造化されたクライアント側アプリケーション(MVVM)との間の関心の分離があることです。

私の回答はここにも当てはまります:

Backboneのようなフレームワークでは、次のようなコードがあります(Backbone Webサイトから取得したものから数行を引いたもの)。

var DocumentView = Backbone.View.extend({

  events: {
    "dblclick"                : "open",
    "click .icon.doc"         : "select",
    "contextmenu .icon.doc"   : "showMenu",
    "click .show_notes"       : "toggleNotes",
    "click .title .lock"      : "editAccessLevel",
    "mouseover .title .date"  : "showTooltip"
  },

  open: function() {
    window.open(this.model.get("viewer_url"));
  },

  select: function() {
    this.model.set({selected: true});
  },

});

ビューであるこのオブジェクトでは、さまざまな要素にイベントハンドラーを設定しています。これらのイベントハンドラーは、モデルに委任するビューオブジェクトの関数を呼び出します。また、さまざまなモデルイベント(などchange)にコールバックを設定し、ビューオブジェクトの関数を呼び出して、それに応じてビューを更新します。

Angularでは、DOMがあなたの見解です。ng-click、などを使用する場合ng-submitは、これらの要素にイベントハンドラーを設定します。これらの要素は、モデルオブジェクトに委任する関数を呼び出します。ng-show、などを使用する場合ng-repeat、ビューを変更するモデルイベントにコールバックを設定します。

AngularJSがこれらの[フックと]コールバックをバックグラウンドで設定するという事実は関係ありません。これとBackboneのようなものとの唯一の違いは、Angularを使用すると、ビューを宣言的に記述できることです。つまり、ビュー何であるかを(必須ではなく)記述して記述できます

したがって、最終的には、<a ng-click="model.set({selected: true})">実際には依存関係を追加することはありません。

events: {
  'click a': 'select'
},

select: function() {
  this.model.set({selected: true});
}

...しかし、それは確かにはるかに少ないコードの地獄です。;)

(注:実際には、Angularバージョンはである必要があり<a ng-click="select()">selectスコープのselectメソッドは、バックボーンの例のビューのメソッドのようになります。)

さて、おそらく正当な懸念は、マークアップのイベントフックが気に入らないということです。個人的に、私はAngularのビューの宣言型の性質を非常に好みます。ここで、マークアップはビューが何であるかを記述し、イベント(ユーザーが生成したものか、モデルの単純な変更かどうか)とビューの間に双方向のバインディングがあります-私は書いていますイベント(特にモデルの変更によって引き起こされるビューの変更)をフックするための定型コードがはるかに少なく、一般的にビューについて推論する方が簡単だと思います。

于 2013-02-10T02:17:07.130 に答える