`this`または` $ scope`を使用する必要がありますか?


251

コントローラー関数へのアクセスに使用されるパターンは2つ thisあり$scopeます。

どちらをいつ使用すればよいですか?thisコントローラに設定され、$scopeビューのスコープチェーンのオブジェクトであることを理解しています。しかし、新しい "Controller as Var"構文を使用すると、どちらも簡単に使用できます。それで、私が求めているのは、何が最良で、将来の方向性は何ですか?

例:

  1. 使用する this

    function UserCtrl() {
      this.bye = function() { alert('....'); };
    }
    <body ng-controller='UserCtrl as uCtrl'>
      <button ng-click='uCtrl.bye()'>bye</button>
  2. 使用する $scope

    function UserCtrl($scope) {
        $scope.bye = function () { alert('....'); };
    }
    <body ng-controller='UserCtrl'>
        <button ng-click='bye()'>bye</button>

私は個人的this.nameに、他のJavascript OOパターンと比較して、見た目がより簡単で、より自然であると感じています。

アドバイスしてください?


'これは' GoogleのI / O 2013のような新しいように思わ使用しm.youtube.com/watch?v=HCR7i5F5L8c:また、この答えをチェックしstackoverflow.com/questions/11605917/...
AlanW

"UserCtrl as uCtrl"構文は新しいですか?1.0.6または1.1.4のngControllerページに記載されていないようです。
Mark Rajcok 2013年

さて、それは新しい1.1.5 ngControllerページに記載されています
Mark Rajcok 2013年

回答:


229

どちらにも用途があります。まず、いくつかの歴史...

$ scopeは「クラシック」な手法ですが、「controller as」はより最近のものです(バージョン1.2.0の時点では公式には、これより前の不安定なプレリリースでは表示されていました)。

どちらも完璧に機能し、唯一の間違った答えは、明確な理由なしに同じアプリでそれらを混ぜることです。率直に言って、それらを混合することは機能しますが、混乱を増すだけです。だから一つ選んでそれと一緒に転がります。最も重要なことは、一貫性を保つことです。

どれ?それはあなた次第です。$ scopeには他にも多くの例がありますが、「コントローラ」は同様に勢いを増しています。一方が他方よりも優れていますか?それは議論の余地があります。では、どのように選ぶのですか?

快適さ

$ scopeを非表示にして、中間オブジェクトを介してコントローラーからビューにメンバーを公開するのが好きなので、私は「コントローラー」を好みます。this。*を設定することで、コントローラーからビューに公開したいものだけを公開できます。$ scopeでもこれを行うことができます。これには標準のJavaScriptを使用することを好みます。実際、次のようにコーディングします。

var vm = this;

vm.title = 'some title';
vm.saveData = function(){ ... } ;

return vm;

これは私にはよりきれいに感じられ、ビューに何が公開されているかを簡単に確認できます。返す変数に「viewmodel」を表す「vm」という名前を付けていることに注意してください。それは私の慣習です。

$ scopeでも同じことができるので、このテクニックを追加したり、邪魔したりすることはありません。

$scope.title = 'some title';
$scope.saveData = function() { ... };

それはあなた次第です。

注入

$ scopeでは、$ scopeをコントローラーに挿入する必要があります。他の理由で必要な場合を除いて、コントローラーでこれを行う必要はありません($ broadcastや時計などですが、コントローラーでは時計を避けようとします)。

更新 私は2つの選択肢についてこの投稿を書きました:http : //www.johnpapa.net/do-you-like-your-angular-controllers-with-or-without-sugar/


4
個人的には、vmを使用したアプローチにも従います。私が見つけた唯一のコードのにおいは、たとえば、イベントのサブスクライブまたはブロードキャスト、コントローラー内のフォーム検証変数へのアクセスなど、$ scopeと具体的にやり取りする必要がある場合です。コントローラを機能として使用している場合でも。
Beyers 2013年

9
正しい。その場合、$ scopeは引き続き使用されますが、サービスとしてより多く使用されます。角度サービス($ scope、$ qなど)を注入すると、必要な機能が提供されます。$ scopeにより、メッセージの監視、適用、使用、およびデータバインディングが可能になります。そして、コントローラをasとして使用する場合でも、$ scopeは引き続き使用され、その抽象化が行われます
John Papa

1
var vm = this;ビューでもそれを 'vm'と呼ぶ必要がありますか?「VMとしてのコントローラー」。それらは同じである必要がありますか?
Javid

2
@JohnPapa-SideWaffleテンプレートが「return vm;」にならないのはなぜですか Controller Asを使用する場合
ケビン

2
@Kevinコントローラーは効果的にCtorとして機能するため、すでに「this」を返します。
John Papa 14

68

$scopeAngular 2.0では削除されています。したがって、thisAngular 2.0のリリース日が近づくにつれ、他の人が従おうとするアプローチが使用されます。


40

私の意見では、JavaScriptの「これ」にはそれ自体で十分な問題があり、別の意味を追加する/使用することは良い考えではありません。

わかりやすくするために、$ scopeを使用します。

更新

ここで説明するように、「コントローラ名」構文があります。私はファンではありませんが、より「公式」のAngularJS構造になっているため、注目に値します。


10
どちらが優れていると言えるかを判断する前に、まず新しい「UserCtrl as uCtrl」構文を理解する必要があると思います。
Mark Rajcok 2013年

'UserCtrl as uCtrl'については、同意する必要があります。これは理解する必要があります。ここでの議論と同じ理由のほとんどのため、それは悪い考えだと思います:groups.google.com/forum
Roy Truelove

4
JSのoopに精通している場合それは完全に理にかなっています。コントローラはクラスであり、angularはコントローラが作成されるたびに新しい演算子を使用します。嫌いでも大丈夫ですが、「これ」の使用に問題があることは誤解を招く恐れがあります。これは「this」の許容可能なユースケースです。
MJ

$ scopeは、明確さには何も追加しません。実際、$ scopeを使用していて、ネストされたスコープがある場合、ビューで何が行われているのかを知るのは非常に難しい場合があります。構文としてのコントローラーとこれを使用することで、より明確になりました。ビューでは、メソッドまたはプロパティがどのコントローラーのスコープから派生しているかがわかりやすく明確です。
ddelrio1986

1
@ ddelrio1986に同意します。ブートストラップタブに問題があり、var vm = $ scopeの使用に問題がありました。タブには独自のスコープがあるため、これを期待どおりに使用することはできませんが、var vm = thisを使用すると、期待どおりに機能します。
user441521

11

Todd Mottoがここで説明しているように、スコープをより簡単にネストできるため、Controller Asの方が優れていると思います。

http://toddmotto.com/digging-into-angulars-controller-as-syntax/

また、常に少なくとも1つあることを保証します。バインド式で、プリミティブにバインドしないでください推奨に従うことを強制します。

さらに、2.0で廃止されるスコープから切り離すことができます。


7

Angularのドキュメントには、使用thisが推奨されていることが明示されています。それ$scopeは、削除されているという事実に加えて、私がを使用しない十分な理由です$scope


4

jason328の「$ scopeはAngular 2.0で削除されている」というのは、私にはもっともな理由のように思えます。そして、私が選択をするのを助ける別の理由を見つけました:thisより読みやすいです-HTMLで見るときfooCtrl.bar、私はの定義を見つける場所をすぐに知っていますbar

更新:thisソリューションに切り替えて間もなく、$scopeタイピングが少なくて済むようになりました


2

私は組み合わせを好みます。

$ scopeの単純なconsole.logと 'this'にモックデータを入力した後、それが表示されます。

$ scopeは、コントローラーのカバー部分の下へのアクセスを許可します。次に例を示します。

$$ChildScope: null;
$$childHead: null;
$$childTail: null;
$$listenerCount: Object;
$$listeners: Object;
$$nextSibling: Scope;
$$prevSibling: null;
$$watchers: null;
$$watcherCount: 0;
$id: 2;
$parent: Object;
foo: 'bar';

** $$を含むプロパティとメソッドは、Angularチームがいじることをお勧めしませんが、$は、$ parentと$ idでクールなことを行うための安全なゲームです。

「これ」は、ポイントに直接到達し、双方向のデータと関数を結び付けます。添付したものだけが表示されます。

foo: 'bar';

では、なぜ私は組み合わせを好むのですか?

UIルーターのネストされたアプリでは、メインコントローラーにアクセスして、子コントローラー内のユニバーサル値と関数を設定および呼び出すことができます。

メインコントローラーで:

// Main Controller
var mainCtrl = this;
mainCtrl.foo = 'Parent at the bar';

子コントローラーで:

// Child Controller
var mainCtrl = $scope.$parent.mainCtrl;
var childCtrl = this;

// update the parent from within the child
childCtrl.underageDrinking = function(){
    mainCtrl.foo = 'Child at the bar';
}

// And then attach the child back to a property on the parent controller!
mainCtrl.currentCtrl = childCtrl;

これで、子の中から親にアクセスでき、親から子にアクセスできます!


1

どちらも機能しますが、スコープに適切なものを$ scopeに適用し、コントローラーに適切なものをコントローラーに適用すると、コードの保守が容易になります。「このコントローラーを構文として忘れてスコープを使用して」と言う人にとっては...同じように機能するかもしれませんが、物事を見失うことなく巨大なアプリケーションを維持できるのでしょうか。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.