AngularJsの「controller as」構文-明確化?


121

私はangularJSから新しい構文について読みましたcontroller as xxx

構文InvoiceController as invoiceは、Angularにコントローラーをインスタンス化して現在のスコープの変数invoiceに保存するように指示します。

視覚化:

ここに画像の説明を入力してください

わかりました、それで私$scopeは私のコントローラーにパラメーターを持っていないので、コードはコントローラーではるかにきれいになります。

だが

ビューで別のエイリアスを指定する必要があります

だから今まで私はできる:

<input type="number" ng-model="qty"  />

....controller('InvoiceController', function($scope) {
   // do something with $scope.qty <--notice

そして今私はできる:

 <input type="number" ng-model="invoic.qty"  /> <-- notice 

  ....controller('InvoiceController', function() {
       // do something with  this.qty  <--notice

質問

それを行う目的は何ですか?ある場所から削除して別の場所に追加しますか?

私は何が欠けているかを見てうれしいです。


8
このビデオはそれを非常によく説明しています。youtube.com/watch?v=tTihyXaz4Bo HTMLのコードを簡潔にするために使用されていると思います。
Fizer Khan

1
明快さ。私は$ scope.xとthis.xをコントローラーで使用することに煩わされていませんが、私の見解では、{{invoice.x}}へのバインディングは、単なる{{x}}(imho)よりも多くを教えてくれます。また、これは、コントローラーの非オブジェクトに問題があるという角度で聞いた問題に対処しているかどうか疑問に思っています(things.xは問題ありませんが、xが問題を引き起こすでしょう)。
マットロバーツ

1
@MattRobertsは最後のコメントに対処します-参照するオブジェクト以外の問題は、JavaScriptのプロトタイプの継承の事実ほどの角度的な問題ではありません。これがなぜangularで起こるのかについての良い説明があります(なぜcontroller asそれを修正するのかとともに)。
Russ Matney 2014

$ scope。$ broadcastをどのように置き換えますか?この新しいケースでは、this。$ broadcastが機能していないようです
Gaurav

1
あなたはまだあなたがなど、いくつかのプロパティの構文、方法、などのコントローラを使用している場合でも、あなたのコントローラに$スコープサービスを注入することができ@Gaurav
デレク

回答:


163

それにはいくつかの点があります。

$scope構文が気に入らない人もいます(理由を聞かないでください)。彼らはただ使うことができると言いますthis。それが目標の一つでした。

プロパティの取得元を明確にすることも非常に役立ちます。

コントローラーをネストすることができ、htmlを読むとき、すべてのプロパティがどこに来るかはかなり明確です。

ドットルールの問題のいくつかを回避することもできます。

たとえば、2つのコントローラーがあり、どちらも同じ名前 'name'を持っている場合、次のようにできます。

<body ng-controller="ParentCtrl">
    <input ng-model="name" /> {{name}}

    <div ng-controller="ChildCtrl">
        <input ng-model="name" /> {{name}} - {{$parent.name}}
    </div>
</body>

親と子の両方を変更できますが、問題はありません。ただし$parent、親の名前を表示するには、を使用する必要があります。これは、子コントローラーでそれをシャドウしたためです。大規模なHTMLコードで$parentは問題が発生する可能性があり、その名前の由来がわかりません。

controller asあなたが行うことができます。

<body ng-controller="ParentCtrl as parent">
    <input ng-model="parent.name" /> {{parent.name}}

    <div ng-controller="ChildCtrl as child">
      <input ng-model="child.name" /> {{child.name}} - {{parent.name}}
    </div>
</body>

同じ例ですが、読む方がはるかに明確です。


10
また、ここでは、このアプローチは、いくつかのために混乱するかもしれない理由のかなり良い例です:stackoverflow.com/questions/25405543/...は
ジュリアン・ホルマン

これは、コントローラーをネストするときに非常に役立ちます。
C_J 2015年

1
私はあなたの答えの同様の実装で問題があります。stackoverflow.com/ questions / 38315538
Cody

これにより、es6クラスをコントローラーとして使用し、HTML内のメソッドを参照することもできます。foo() { ... }よりもずっときれいです$scope.foo = function() { ... }
Brian McCutchon

17

controller as私が見る構文の主な利点は、$ scope-decorating関数だけでなく、コントローラーをクラスとして操作し、継承を利用できることです。多くのコントローラーに非常によく似た機能がある場合によく遭遇します。最も明白なことは、BaseControllerクラスを作成してそれから継承することです。

この問題を部分的に解決する$ scope継承がありますが、一部の人々は、よりOOPの方法でコードを書くことを好むため、私の意見では、コードの推論とテストが容易になります。

ここにデモンストレーションのフィドルがあります:http : //jsfiddle.net/HB7LU/5796/


1
フィドルは本当に便利であるように、これは、より多くのupvotesを取得する必要があります
Mawgはモニカ回復言う

13

ネストされたスコープがある場合、1つの特定の利点は明らかです。これで、プロパティ参照のスコープが完全に明確になります。


7

ソース

を使用したコントローラの作成$scope object“controller as”構文およびvmの使用の違い

$ scopeオブジェクトを使用してコントローラーを作成する

通常、以下のリストに示すように、$ scopeオブジェクトを使用してコントローラーを作成します。

myApp.controller("AddController", function ($scope) {



    $scope.number1;

    $scope.number2;

    $scope.result;

    $scope.add = function () {

        $scope.result = $scope.number1 + $scope.number2;

    }

});

上記では、$ scopeオブジェクトコントローラーとビューを使用して、3つの変数と1つの動作を持つAddControllerを作成しています。$ scopeオブジェクトは、データと動作をビューに渡すために使用されます。ビューとコントローラーを接着します。

基本的に、$ scopeオブジェクトは次のタスクを実行します。

  1. コントローラからビューにデータを渡す

  2. コントローラーからビューに動作を渡す

  3. コントローラーを接着して一緒に表示

  4. $ scopeオブジェクトはビューが変更されると変更され、ビューは$ scopeオブジェクトのプロパティが変更されると変更されます

プロパティを$ scopeオブジェクトにアタッチして、データと動作をビューに渡します。コントローラーで$ scopeオブジェクトを使用する前に、依存関係としてコントローラー関数に渡す必要があります。

「controller as」構文とvmを使用する

以下のリストに示すように、構文としてコントローラーとvm変数を使用して、上記のコントローラーを書き換えることができます。

myApp.controller("AddVMController", function () {

    var vm = this;

    vm.number1 = undefined;

    vm.number2=undefined;

    vm.result =undefined;

    vm.add = function () {

        vm.result = vm.number1 + vm.number2;

    }

});

基本的に、これを変数vmに割り当ててから、プロパティと動作をそれに関連付けます。ビューでは、コントローラーを構文として使用してAddVmControllerにアクセスできます。これは以下のリストに示されています。

<div ng-controller="AddVMController as vm">

            <input ng-model="vm.number1" type="number" />

            <input ng-model="vm.number2" type="number" />

            <button class="btn btn-default" ng-click="vm.add()">Add</button>

            <h3>{{vm.result}}</h3>

  </div>

もちろん、構文としてコントローラーで「vm」以外の名前を使用できます。内部で、AngularJSは$ scopeオブジェクトを作成し、プロパティと動作を関連付けます。ただし、コントローラーを構文として使用することで、コードはコントローラーで非常にクリーンになり、エイリアス名のみがビューに表示されます。

コントローラを構文として使用するためのいくつかの手順を次に示します。

  1. $ scopeオブジェクトなしでコントローラーを作成します。

  2. これをローカル変数に割り当てます。私はvmとして変数名を優先しました。任意の名前を選択できます。

  3. データと動作をvm変数にアタッチします。

  4. ビューで、コントローラーを構文として使用して、コントローラーにエイリアスを指定します。

  5. エイリアスには任意の名前を付けることができます。ネストされたコントローラーを使用していない限り、私はvmを使用することを好みます。

コントローラーを作成する際、$ scopeオブジェクトのアプローチまたはコントローラーを構文として使用することの直接的な利点や欠点はありません。これは純粋に選択の問題ですが、コントローラを構文として使用すると、コントローラのJavaScriptコードが読みやすくなり、このコンテキストに関連する問題が防止されます。

$ scopeオブジェクトアプローチでネストされたコントローラー

以下のリストに示すように、2つのコントローラーがあります。

myApp.controller("ParentController", function ($scope) {



    $scope.name = "DJ";

    $scope.age = 32;

});

myApp.controller("ChildController", function ($scope) {



    $scope.age = 22;

    $scope.country = "India";



});

プロパティ「age」は両方のコントローラーの内部にあり、ビューではこれらの2つのコントローラーを次のリストに示すようにネストできます。

<div ng-controller="ParentController">



            <h2>Name :{{name}} </h2>

            <h3>Age:{{age}}</h3>



             <div ng-controller="ChildController">

                    <h2>Parent Name :{{name}} </h2>

                    <h3>Parent Age:{{$parent.age}}</h3>

                    <h3>Child Age:{{age}}</h3>

                    <h3>Country:{{country}}</h3>

             </div>

        </div>

ご覧のとおり、親コントローラーのageプロパティにアクセスするには、$ parent.ageを使用しています。ここではコンテキストの分離はあまり明確ではありません。しかし、コントローラーを構文として使用すると、ネストされたコントローラーをよりエレガントな方法で操作できます。以下のリストに示すようなコントローラーがあるとします。

myApp.controller("ParentVMController", function () {

    var vm = this;

    vm.name = "DJ";

    vm.age = 32;

});

myApp.controller("ChildVMController", function () {

    var vm = this;

    vm.age = 22;

    vm.country = "India";



});

ビューでは、以下のリストに示すように、これら2つのコントローラーをネストできます。

<div ng-controller="ParentVMController as parent">



            <h2>Name :{{parent.name}} </h2>

            <h3>Age:{{parent.age}}</h3>



            <div ng-controller="ChildVMController as child">

                <h2>Parent Name :{{parent.name}} </h2>

                <h3>Parent Age:{{parent.age}}</h3>

                <h3>Child Age:{{child.age}}</h3>

                <h3>Country:{{child.country}}</h3>

            </div>

 </div>

構文としてのコントローラーには、より読みやすいコードがあり、$ parent構文を使用する代わりに、親コントローラーのエイリアス名を使用して親プロパティにアクセスできます。

コントローラーを構文として使用するか、$ scopeオブジェクトとして使用するかは純粋にあなたの選択であると言って、この投稿を締めくくります。ビューにネストされたコントローラーが明確に分かれていることを考えると、コンテキストに対して制御できる構文としてのコントローラーの方が扱いやすいという点で、どちらにも大きな利点や欠点はありません。


4

メソッド/プロパティはスコープオブジェクトではなくコントローラーインスタンスに直接関連付けられているため、主な利点はより直感的なAPIであることがわかります。基本的に、古いアプローチでは、コントローラーはスコープオブジェクトを構築するための装飾にすぎません。

これに関するいくつかの詳細は次のとおりです:http : //www.syntaxsuccess.com/viewarticle/551798f20c5f3f3c0ffcc9ff


3

私が読んだことから、Angular 2.0では$ scopeが削除されるか、少なくとも$ scopeの使用方法がどのように表示されるかがわかります。2.0のリリースが近づいているので、コントローラを使い始めるのは良いことかもしれません。

詳細については、こちらのビデオリンクをご覧ください

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