AngularJs "Controller as" -Syntax - Klarstellung?

121

Ich habe über die neue Syntax von angleJS bezüglich gelesencontroller as xxx

Die Syntax InvoiceController as invoiceweist Angular an, den Controller zu instanziieren und in der Variablenrechnung im aktuellen Bereich zu speichern.

Visualisierung:

Geben Sie hier die Bildbeschreibung ein

Ok, ich habe den Parameter nicht $scopein meinem Controller und der Code wird im Controller viel sauberer.

Aber

Ich muss einen anderen Alias in der Ansicht angeben

Also bis jetzt konnte ich tun:

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

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

Und jetzt kann ich tun:

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

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

Frage

Was ist das Ziel dabei? von einem Ort entfernen und an einen anderen Ort hinzufügen?

Ich werde froh sein zu sehen, was mir fehlt.

Royi Namir
quelle
8
Dieses Video erklärt es sehr gut. youtube.com/watch?v=tTihyXaz4Bo Ich denke, es wird für saubereren Code im HTML verwendet.
Fizer Khan
1
Klarheit. Ich habe nicht die Mühe, $ scope.x Vs this.x im Controller zu verwenden, aber meiner Ansicht nach sagt mir die Bindung an {{rechnung.x}} mehr als nur {{x}} (imho). Außerdem frage ich mich, ob dies ein Problem behebt, von dem ich in einem Winkel gehört habe, in dem Nicht-Objekte im Controller Probleme haben (also wäre things.x in Ordnung, aber x würde ein Problem verursachen).
Matt Roberts
1
@MattRoberts, um Ihren letzten Kommentar anzusprechen - das Nicht-Objekt-Problem, auf das Sie verweisen, ist weniger ein Winkelproblem als eine Tatsache der prototypischen Vererbung von Javascript. Es gibt eine gute Erklärung dafür, warum es hier im Winkel passiert (zusammen mit dem Grund, warum es controller asbehoben wird).
Russ Matney
Wie ersetze ich $ scope. $ Broadcast? in diesem neuen Fall, weil meine this. $ -Sendung nicht zu funktionieren scheint
Gaurav
1
@ Gaurav Sie können immer noch den $ scope-Dienst in Ihren Controller einfügen, auch wenn Sie den Controller als Syntax für einige Eigenschaften, Methoden usw. verwenden
Derek

Antworten:

163

Es gibt verschiedene Dinge.

Einige Leute mögen die $scopeSyntax nicht (frag mich nicht warum). Sie sagen, dass sie nur gebrauchen könnten this. Das war eines der Ziele.

Es ist auch sehr nützlich, klar zu machen, woher eine Immobilie stammt.

Sie können Controller verschachteln, und beim Lesen des HTML-Codes ist ziemlich klar, woher jede Eigenschaft kommt.

Sie können auch vermeiden , einige der Punkt Regel Probleme.

Wenn Sie beispielsweise zwei Controller mit demselben Namen 'name' haben, können Sie Folgendes tun:

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

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

Sie können sowohl Eltern als auch Kinder ändern, kein Problem. Sie müssen jedoch verwenden $parent, um den Namen des Elternteils anzuzeigen, da Sie ihn in Ihrem untergeordneten Controller beschattet haben. In massiven HTML-Code $parentkönnte problematisch sein, Sie wissen nicht, woher dieser Name kommt.

Mit können controller asSie tun:

<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>

Gleiches Beispiel, aber es ist viel klarer zu lesen.

Jesus Rodriguez
quelle
10
Auch hier ist ein ziemlich gutes Beispiel dafür, warum dieser Ansatz für einige verwirrend sein könnte: stackoverflow.com/questions/25405543/…
Julian Hollmann
Dies ist sehr hilfreich, wenn Sie Controller verschachteln!
C_J
1
Ich habe Probleme mit einer ähnlichen Implementierung Ihrer Antwort, siehe stackoverflow.com/questions/38315538
Cody
Auf diese Weise können Sie auch eine es6-Klasse als Controller verwenden und auf die Methoden im HTML verweisen. foo() { ... }ist viel sauberer als $scope.foo = function() { ... }.
Brian McCutchon
17

Der Hauptvorteil der controller asSyntax, den ich sehe, besteht darin, dass Sie mit Controllern als Klassen arbeiten können, nicht nur mit einigen Funktionen zum Dekorieren von $ scope, und die Vererbung nutzen können. Ich stoße oft auf eine Situation, in der es eine Funktionalität gibt, die einer Reihe von Controllern sehr ähnlich ist, und das naheliegendste ist, eine BaseControllerKlasse zu erstellen und davon zu erben.

Obwohl es eine $ scope-Vererbung gibt, die dieses Problem teilweise löst, bevorzugen einige Leute es, Code auf eine OOP-Weise zu schreiben, was meiner Meinung nach das Nachdenken und Testen des Codes erleichtert.

Hier ist eine Geige zum Demonstrieren: http://jsfiddle.net/HB7LU/5796/

Roman Kolpak
quelle
1
Dies sollte mehr positive Stimmen bekommen, da die Geige wirklich hilfreich ist
Mawg sagt, Monica
13

Ich glaube, ein besonderer Vorteil liegt auf der Hand, wenn Sie Bereiche verschachtelt haben. Es ist nun völlig klar, aus welchem ​​Bereich eine Eigenschaftsreferenz stammt.

David M. Karr
quelle
7

Quelle

Unterschied zwischen dem Erstellen eines Controllers mit $scope objectder “controller as”Syntax und vm

Erstellen eines Controllers mit dem Objekt $ scope

Normalerweise erstellen wir einen Controller mit dem $ scope-Objekt, wie in der folgenden Liste gezeigt:

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



    $scope.number1;

    $scope.number2;

    $scope.result;

    $scope.add = function () {

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

    }

});

Oben erstellen wir den AddController mit drei Variablen und einem Verhalten unter Verwendung des $ scope-Objektcontrollers und der Ansicht, die miteinander kommunizieren. Das $ scope-Objekt wird verwendet, um Daten und Verhalten an die Ansicht zu übergeben. Es klebt die Ansicht und den Controller zusammen.

Im Wesentlichen führt das $ scope-Objekt die folgenden Aufgaben aus:

  1. Übergeben Sie Daten vom Controller an die Ansicht

  2. Übergeben Sie das Verhalten vom Controller an die Ansicht

  3. Klebt den Controller und die Ansicht zusammen

  4. Das $ scope-Objekt wird geändert, wenn sich eine Ansicht ändert, und eine Ansicht wird geändert, wenn sich die Eigenschaften des $ scope-Objekts ändern

Wir hängen Eigenschaften an ein $ scope-Objekt an, um Daten und Verhalten an die Ansicht zu übergeben. Bevor Sie das $ scope-Objekt im Controller verwenden, müssen Sie es in der Controller-Funktion als Abhängigkeiten übergeben.

Verwenden der Syntax "controller as" und vm

Wir können den obigen Controller unter Verwendung des Controllers als Syntax und der VM-Variablen wie in der folgenden Liste gezeigt umschreiben:

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;

    }

});

Im Wesentlichen weisen wir dies einer Variablen vm zu und fügen dieser dann eine Eigenschaft und ein Verhalten hinzu. In der Ansicht können wir mit Controller als Syntax auf den AddVmController zugreifen. Dies wird in der folgenden Liste gezeigt:

<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>

Natürlich können wir im Controller einen anderen Namen als "vm" als Syntax verwenden. Unter der Haube erstellt AngularJS das $ scope-Objekt und hängt die Eigenschaften und das Verhalten an. Wenn Sie jedoch den Controller als Syntax verwenden, ist der Code auf dem Controller sehr sauber und nur der Aliasname ist in der Ansicht sichtbar.

Hier sind einige Schritte, um den Controller als Syntax zu verwenden:

  1. Erstellen Sie einen Controller ohne $ scope-Objekt.

  2. Weisen Sie dies einer lokalen Variablen zu. Ich habe den Variablennamen als vm bevorzugt. Sie können einen beliebigen Namen Ihrer Wahl wählen.

  3. Hängen Sie Daten und Verhalten an die Variable vm an.

  4. Geben Sie in der Ansicht dem Controller einen Alias, indem Sie den Controller als Syntax verwenden.

  5. Sie können dem Alias ​​einen beliebigen Namen geben. Ich bevorzuge die Verwendung von VM, es sei denn, ich arbeite nicht mit verschachtelten Controllern.

Beim Erstellen des Controllers gibt es keine direkten Vor- oder Nachteile der Verwendung des $ scope-Objektansatzes oder des Controllers als Syntax. Es ist jedoch nur eine Frage der Wahl, ob die Verwendung des Controllers als Syntax den JavaScript-Code des Controllers besser lesbar macht und Probleme im Zusammenhang mit diesem Kontext verhindert.

Verschachtelte Controller im $ scope-Objektansatz

Wir haben zwei Controller, wie in der folgenden Liste gezeigt:

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



    $scope.name = "DJ";

    $scope.age = 32;

});

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



    $scope.age = 22;

    $scope.country = "India";



});

Die Eigenschaft "Alter" befindet sich in beiden Controllern. In der Ansicht können diese beiden Controller wie in der folgenden Liste gezeigt verschachtelt werden:

<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>

Wie Sie sehen, verwenden wir für den Zugriff auf die age-Eigenschaft des übergeordneten Controllers die Datei $ parent.age. Die Kontexttrennung ist hier nicht sehr klar. Mit dem Controller als Syntax können wir jedoch eleganter mit verschachtelten Controllern arbeiten. Nehmen wir an, wir haben Controller wie in der folgenden Liste gezeigt:

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";



});

In der Ansicht können diese beiden Controller wie in der folgenden Liste gezeigt verschachtelt werden:

<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>

Im Controller als Syntax haben wir besser lesbaren Code und auf die übergeordnete Eigenschaft kann mit dem Aliasnamen des übergeordneten Controllers zugegriffen werden, anstatt mit der übergeordneten Syntax $.

Ich werde diesen Beitrag mit der Aussage abschließen, dass es nur Ihre Wahl ist, ob Sie den Controller als Syntax oder das $ scope-Objekt verwenden möchten. Es gibt auch keinen großen Vor- oder Nachteil, einfach, dass der Controller als Syntax, die Sie im Kontext steuern können, etwas einfacher zu handhaben ist, da die verschachtelten Controller in der Ansicht klar voneinander getrennt sind.

ShibinRagh
quelle
4

Ich finde, der Hauptvorteil ist eine intuitivere API, da die Methoden / Eigenschaften direkt mit der Controller-Instanz und nicht mit dem Scope-Objekt verknüpft sind. Grundsätzlich wird der Controller mit dem alten Ansatz nur zu einer Dekoration für den Aufbau des Scope-Objekts.

Hier einige weitere Informationen dazu: http://www.syntaxsuccess.com/viewarticle/551798f20c5f3f3c0ffcc9ff

TGH
quelle
3

Nach dem, was ich gelesen habe, wird $ scope in Angular 2.0 entfernt, oder zumindest wie wir die Verwendung von $ scope sehen. Es könnte sinnvoll sein, den Controller zu verwenden, wenn sich die Veröffentlichung von 2.0 nähert.

Videolink hier für weitere Diskussionen.

jason328
quelle