Soll ich "this" oder "$ scope" verwenden?


251

Für den Zugriff auf Steuerungsfunktionen werden zwei Muster verwendet: thisund $scope.

Welches soll ich wann verwenden? Ich verstehe, thisist auf den Controller eingestellt und $scopeist ein Objekt in der Scope-Kette für Ansichten. Mit der neuen Syntax "Controller as Var" können Sie jedoch problemlos beide verwenden. Ich frage also, was am besten ist und in welche Richtung es für die Zukunft geht.

Beispiel:

  1. Verwenden von this

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

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

Ich persönlich finde das this.nameaugenschonender und natürlicher im Vergleich zu anderen Javascript OO-Mustern.

Ratschlag bitte?


Die Verwendung von "Dies" scheint ab Google I / O 2013 neu zu sein. M.youtube.com/watch?v=HCR7i5F5L8c Überprüfen Sie auch diese Antwort: stackoverflow.com/questions/11605917/…
AlanW

Ist die Syntax "UserCtrl as uCtrl" neu? Ich sehe es nicht auf den Seiten 1.0.6 oder 1.1.4 ngController dokumentiert.
Mark Rajcok

Okay, es ist auf der neuen Seite 1.1.5 ngController dokumentiert .
Mark Rajcok

1
Beste Erklärungen für $ scope und dieses codetunnel.io/angularjs-controller-as-or-scope
Sai

Antworten:


229

Beide haben ihre Verwendung. Zunächst etwas Geschichte ...

$ scope ist die "klassische" Technik, während "controller as" viel neuer ist (ab Version 1.2.0 offiziell, obwohl es zuvor in instabilen Vorabversionen erschienen ist).

Beide funktionieren einwandfrei und die einzige falsche Antwort ist, sie ohne expliziten Grund in derselben App zu mischen. Ehrlich gesagt wird das Mischen funktionieren, aber es wird nur zur Verwirrung beitragen. Also wählen Sie eine aus und rollen Sie damit. Das Wichtigste ist, konsequent zu sein.

Welcher? Das hängt von dir ab. Es gibt noch viele weitere Beispiele für $ scope, aber auch "controller as" nimmt Fahrt auf. Ist einer besser als der andere? Das ist umstritten. Wie wählst du?

Komfort

Ich bevorzuge den "Controller als", weil ich den $ scope gerne verstecke und die Mitglieder vom Controller über ein Zwischenobjekt der Ansicht aussetze. Durch Einstellen dieser Option. * Kann ich genau das anzeigen, was ich vom Controller für die Ansicht verfügbar machen möchte. Sie können dies auch mit $ scope tun. Ich bevorzuge nur die Verwendung von Standard-JavaScript. Tatsächlich codiere ich es so:

var vm = this;

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

return vm;

Das fühlt sich für mich sauberer an und macht es einfach zu sehen, was der Sicht ausgesetzt ist. Beachten Sie, dass ich die Variable, die ich zurückgebe, "vm" nenne, was für viewmodel steht. Das ist nur meine Konvention.

Mit $ scope kann ich die gleichen Dinge tun, also füge ich die Technik nicht hinzu oder lenke sie nicht ab.

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

Es liegt also an Ihnen.

Injektion

Mit $ scope muss ich $ scope in den Controller einfügen. Ich muss dies nicht mit Controller als tun, es sei denn, ich brauche es aus einem anderen Grund (wie $ Broadcast oder Uhren, obwohl ich versuche, Uhren im Controller zu vermeiden).

UPDATE Ich habe diesen Beitrag über die 2 Auswahlmöglichkeiten geschrieben: http://www.johnpapa.net/do-you-like-your-angular-controllers-with-or-without-sugar/


4
Persönlich verfolge ich Ihren Ansatz auch mit vm. Der einzige Code-Geruch, den ich wahrgenommen habe, ist, wenn Sie speziell mit $ scope interagieren müssen, z. B. Ereignisse abonnieren oder senden, auf Formularvalidierungsvariablen in Ihrem Controller zugreifen usw. Dies führt zu einer etwas gemischten Umgebung, in die Sie $ scope noch einfügen müssen obwohl Sie den Controller als Funktion verwenden.
Beyers

9
Richtig. $ scope wird in diesem Fall weiterhin verwendet, wird jedoch eher als Dienst verwendet. Wenn wir Winkeldienste ($ scope, $ q usw.) einfügen, bieten sie einige Funktionen, die wir benötigen. Mit $ scope können wir Nachrichten beobachten, anwenden, verwenden sowie Daten binden. Und selbst wenn Controller als verwendet wird, wird $ scope immer noch verwendet, es ist nur abstrahiert
John Papa

1
var vm = this;Müssen Sie es in der Ansicht auch "vm" nennen? 'controller as vm'. Müssen sie gleich sein?
Javid

2
@JohnPapa - Warum geben die SideWaffle-Vorlagen nicht "return vm;" bei Verwendung von Controller As?
Kevin

2
@ Kevin Controller fungieren effektiv als Ctor und geben daher bereits "dies" zurück.
John Papa

68

$scopewird in Angular 2.0 entfernt. Daher thiswäre die Verwendung ein Ansatz, dem andere folgen möchten, wenn das Veröffentlichungsdatum von Angular 2.0 näher rückt.


40

Meiner Meinung nach hat 'dies' in Javascript genug Probleme für sich und das Hinzufügen einer anderen Bedeutung / Verwendung dafür ist keine gute Idee.

Ich würde aus Gründen der Klarheit $ scope verwenden.

AKTUALISIEREN

Es gibt jetzt die hier diskutierte Syntax 'controller as' . Ich bin kein Fan, aber jetzt, da es ein "offizielleres" AngularJS-Konstrukt ist, verdient es etwas Aufmerksamkeit.


10
Ich denke, wir müssen zuerst die neue Syntax "UserCtrl as uCtrl" verstehen, bevor wir sagen können, was wir für besser halten.
Mark Rajcok

Zu 'UserCtrl as uCtrl' stimme ich zu, dies muss verstanden werden. Ich denke, es ist eine schlechte Idee, aus den meisten der gleichen Gründe wie die hier vorgebrachten
Roy Truelove

4
Wenn Sie mit oop in JS vertraut sind, ist dies absolut sinnvoll. Ein Controller ist eine Klasse, und Angular verwendet den neuen Operator jedes Mal, wenn ein Controller erstellt wird. Sie können es gerne ablehnen, aber es ist irreführend zu behaupten, dass es Probleme bei der Verwendung von "dies" gibt. Es ist ein akzeptabler Anwendungsfall für "dies".
MJ

$ scope trägt nichts zur Klarheit bei. Tatsächlich kann es sehr schwierig sein zu wissen, was in der Ansicht vor sich geht, wenn Sie $ scope verwenden und Sie verschachtelte Bereiche haben. Der Controller als Syntax sorgt zusammen mit dieser für mehr Klarheit. In der Ansicht ist es schön und klar, aus welchem ​​Controller-Bereich eine Methode oder Eigenschaft stammt.
ddelrio1986

1
Ich stimme @ ddelrio1986 zu. Hatte gerade ein Problem mit Bootstrap-Registerkarten und agular mit der Verwendung von var vm = $ scope. Registerkarten haben ihren eigenen Bereich und können daher nicht wie erwartet verwendet werden. Mit var vm = this funktionieren die Dinge jedoch wie erwartet.
user441521


7

In der Angular-Dokumentation wird ausdrücklich darauf hingewiesen, dass die Verwendung thisempfohlen wird. Das ist neben der Tatsache, dass $scopees entfernt wird, Grund genug für mich, es niemals zu benutzen $scope.


4

jason328s "$ scope wird in Angular 2.0 entfernt" klingt für mich nach einem guten Grund. Und ich habe einen weiteren Grund gefunden, mir bei der Auswahl zu helfen: thisist besser lesbar - wenn ich fooCtrl.barin HTML sehe, weiß ich sofort, wo ich die Definition von finden kann bar.

Updates: Kurz nach dem Wechsel zur thisLösung begann ich, $scopeWege zu verpassen , die weniger Eingabe erfordern


2

Ich bevorzuge eine Kombination.

Ein einfaches console.log von $ scope und 'this' nach dem Auffüllen mit einigen Scheindaten zeigt Ihnen dies.

$ scope ermöglicht den Zugriff auf unter dem Deckmantel liegende Teile eines Controllers, zum Beispiel:

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

** Eigenschaften und Methoden mit $$ werden vom Angular-Team nicht empfohlen, um damit herumzuspielen, aber das $ kann ein sicheres Spiel sein, um coole Sachen mit $ parent und $ id zu machen.

'this' bringt es auf den Punkt und fügt 2-Wege-gebundene Daten und Funktionen hinzu. Sie sehen nur, was Sie angehängt haben:

foo: 'bar';

Warum bevorzuge ich eine Kombination?

In verschachtelten Apps von UI-Routern kann ich auf den Hauptcontroller zugreifen, universelle Werte und Funktionen in einem untergeordneten Controller festlegen und aufrufen:

In der Hauptsteuerung:

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

In der untergeordneten Steuerung:

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

Jetzt können Sie von Kind zu Kind auf Eltern und von Eltern zu Kind zugreifen!


1

Beides funktioniert, aber wenn Sie Dinge, die für den Bereich geeignet sind, auf $ scope anwenden und wenn Sie Dinge, die für den Controller geeignet sind, auf den Controller anwenden, ist Ihr Code einfach zu pflegen. Für die Leute, die sagen "Ugh, benutze einfach den Bereich, vergiss diesen Controller als Syntax" ... Es mag genauso funktionieren, aber ich frage mich, wie du eine riesige Anwendung warten kannst, ohne den Überblick zu verlieren.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.