Im Abschnitt "Komponenten erstellen" der AngularJS-Homepage gibt es dieses Beispiel:
controller: function($scope, $element) {
var panes = $scope.panes = [];
$scope.select = function(pane) {
angular.forEach(panes, function(pane) {
pane.selected = false;
});
pane.selected = true;
}
this.addPane = function(pane) {
if (panes.length == 0) $scope.select(pane);
panes.push(pane);
}
}
Beachten Sie, wie die select
Methode hinzugefügt wird $scope
, aber die addPane
Methode hinzugefügt wird this
. Wenn ich es ändere $scope.addPane
, bricht der Code.
Die Dokumentation besagt, dass es tatsächlich einen Unterschied gibt, aber es wird nicht erwähnt, was der Unterschied ist:
In früheren Versionen von Angular (vor 1.0 RC) konnten Sie
this
die$scope
Methode austauschbar verwenden. Dies ist jedoch nicht mehr der Fall. Innerhalb von Methoden, die im Bereich definiert sindthis
und$scope
austauschbar sind (Winkelsätzethis
auf$scope
), aber nicht anders in Ihrem Controller-Konstruktor.
Wie funktioniert this
und $scope
funktioniert in AngularJS-Controllern?
angularjs
angularjs-scope
this
Alexei Boronine
quelle
quelle
Antworten:
Kurze Antwort :
this
this
ist dies der Controller.$scope
Objekt definierte Funktion aufgerufen wird,this
ist der "Gültigkeitsbereich gültig, als die Funktion aufgerufen wurde". Dies kann (oder auch nicht!) Sein, auf dem$scope
die Funktion definiert ist. Also, innerhalb der Funktionthis
und$scope
möglicherweise nicht gleich.$scope
$scope
Objekt zugeordnet.$scope
.$scope
HTML / view kann nur auf Methoden zugegriffen werden, die für dieses Objekt definiert sind (und übergeordnete Bereichsobjekte, wenn die prototypische Vererbung im Spiel ist). ZB vonng-click
, Filtern usw.Lange Antwort :
Eine Controller-Funktion ist eine JavaScript-Konstruktorfunktion. Wenn die Konstruktorfunktion ausgeführt wird (z. B. wenn eine Ansicht geladen wird),
this
(dh der "Funktionskontext"), wird das Controller-Objekt festgelegt. Also in der Controller-Konstruktorfunktion "tabs", wenn die addPane-Funktion erstellt wirdEs wird auf dem Controller-Objekt erstellt, nicht auf $ scope. Ansichten können die Funktion addPane nicht sehen - sie haben nur Zugriff auf Funktionen, die in $ scope definiert sind. Mit anderen Worten, im HTML funktioniert dies nicht:
Nachdem die Controller-Konstruktorfunktion "tabs" ausgeführt wurde, haben wir Folgendes:
Die gestrichelte schwarze Linie zeigt die prototypische Vererbung an - ein isolierter Bereich erbt prototypisch von Scope . (Es erbt nicht prototypisch von dem Gültigkeitsbereich, in dem die Direktive im HTML gefunden wurde.)
Jetzt möchte die Link-Funktion der Pane-Direktive mit der Tabs-Direktive kommunizieren (was wirklich bedeutet, dass sie die Tabs in irgendeiner Weise beeinflussen muss, um den Bereich zu isolieren). Ereignisse könnten verwendet werden, aber ein anderer Mechanismus besteht darin, dass die Fensteranweisung
require
den Registerkarten-Controller enthält. (Es scheint keinen Mechanismus für die Fensteranweisung zurequire
den Registerkarten $ scope zu geben.)Dies wirft also die Frage auf: Wenn wir nur Zugriff auf den Tabs-Controller haben, wie erhalten wir Zugriff auf die Tabs, die $ scope isolieren (was wir wirklich wollen)?
Nun, die rot gepunktete Linie ist die Antwort. Der "Bereich" der Funktion addPane () (ich beziehe mich hier auf den Funktionsumfang / die Schließungen von JavaScript) ermöglicht der Funktion den Zugriff auf die Registerkarten, die $ scope isolieren. Dh addPane () hat Zugriff auf die "Registerkarten IsolateScope" im obigen Diagramm aufgrund eines Abschlusses, der beim Definieren von addPane () erstellt wurde. (Wenn wir stattdessen addPane () für das tabs $ scope-Objekt definieren würden, hätte die pane-Direktive keinen Zugriff auf diese Funktion und hätte daher keine Möglichkeit, mit den tabs $ scope zu kommunizieren.)
Zur Beantwortung des anderen Teils Ihrer Frage:
how does $scope work in controllers?
:In Funktionen, die für $ scope definiert sind,
this
wird "der Gültigkeitsbereich von $ festgelegt, in dem / wann die Funktion aufgerufen wurde". Angenommen, wir haben den folgenden HTML-Code:Und das hat
ParentCtrl
(allein)Wenn Sie auf den ersten Link klicken, wird dies angezeigt
this
und$scope
ist identisch, da " der Gültigkeitsbereich, der beim Aufruf der Funktion gültig war " der mit dem verknüpfte Gültigkeitsbereich istParentCtrl
.Den zweiten Link klicken , wird verraten
this
und$scope
sind nicht gleich, da „ der Umfang in Kraft , wenn die Funktion aufgerufen wurde “ ist der Umfang im Zusammenhang mit derChildCtrl
. Also hierthis
ist aufChildCtrl
's gesetzt$scope
. Innerhalb der Methode$scope
befindet sich immer noch der BereichParentCtrl
$.Geige
Ich versuche, nicht
this
innerhalb einer in $ scope definierten Funktion zu verwenden, da es verwirrend wird, welcher $ scope betroffen ist, insbesondere wenn man bedenkt, dass ng-repeat, ng-include, ng-switch und Direktiven alle ihre eigenen untergeordneten Bereiche erstellen können.quelle
Der Grund, warum 'addPane' diesem zugewiesen wird, liegt in der
<pane>
Direktive.Die
pane
Direktive tutrequire: '^tabs'
, die das Registerkarten-Controller-Objekt von einer übergeordneten Direktive in die Verknüpfungsfunktion einfügt.addPane
wird zugewiesen,this
damit diepane
Link-Funktion es sehen kann. Dann ist in derpane
Link-FunktionaddPane
nur eine Eigenschaft destabs
Controllers und es ist nur tabsControllerObject.addPane. Die Verknüpfungsfunktion der Pane-Direktive kann also auf das Registerkarten-Controller-Objekt und damit auf die addPane-Methode zugreifen.Ich hoffe, meine Erklärung ist klar genug. Es ist schwer zu erklären.
quelle
Ich habe gerade eine ziemlich interessante Erklärung über den Unterschied zwischen den beiden gelesen und eine wachsende Präferenz, Modelle an den Controller anzuhängen und den Controller als Alias zu verwenden, um Modelle an die Ansicht zu binden. http://toddmotto.com/digging-into-angulars-controller-as-syntax/ ist der Artikel.
Er erwähnt es nicht, aber wenn Sie beim Definieren von Direktiven etwas zwischen mehreren Direktiven teilen müssen und keinen Dienst wünschen (es gibt legitime Fälle, in denen Dienste problematisch sind), hängen Sie die Daten an den Controller der übergeordneten Direktive an.
Der
$scope
Dienst bietet viele nützliche Dinge,$watch
die am offensichtlichsten sind. Wenn Sie jedoch nur Daten an die Ansicht binden müssen, ist die Verwendung des einfachen Controllers und des "Controllers als" in der Vorlage in Ordnung und wahrscheinlich vorzuziehen.quelle
Ich empfehle Ihnen, den folgenden Beitrag zu lesen: AngularJS: "Controller as" oder "$ scope"?
Es beschreibt sehr gut die Vorteile der Verwendung von "Controller as", um Variablen gegenüber "$ scope" verfügbar zu machen.
Ich weiß, dass Sie speziell nach Methoden und nicht nach Variablen gefragt haben, aber ich denke, dass es besser ist, sich an eine Technik zu halten und mit dieser übereinzustimmen.
Meiner Meinung nach ist es aufgrund des im Beitrag behandelten Variablenproblems besser, einfach die Technik "Controller as" zu verwenden und sie auch auf die Methoden anzuwenden.
quelle
In diesem Kurs ( https://www.codeschool.com/courses/shaping-up-with-angular-js ) erklären sie, wie man "dies" und viele andere Dinge verwendet.
Wenn Sie dem Controller über "diese" Methode eine Methode hinzufügen, müssen Sie diese in der Ansicht mit dem Namen des Controllers "dot" für Ihre Eigenschaft oder Methode aufrufen.
Wenn Sie beispielsweise Ihren Controller in der Ansicht verwenden, haben Sie möglicherweise folgenden Code:
quelle
$scope
Dank, dass Sie ihn erwähnt haben.as
undthis
wie kann es helfen , den Unterschied zu erklären?$scope
nie erwähnt, habe ich gelernt, nurthis
in den Controllern zu verwenden. Das Problem ist, dass Sie, wenn Sie anfangen, Versprechen in Ihrem Controller zu behandeln, viele Referenzproblemethis
haben und anfangen müssen, Dinge wievar me = this
das Referenzieren des Modellsthis
innerhalb der Versprechen-Rückgabefunktion zu tun . Aus diesem Grund bin ich immer noch sehr verwirrt darüber, welche Methode ich verwenden soll$scope
oderthis
.var me = this
oder.bind(this)
wann immer du Versprechen machst oder andere Dinge, die den Verschluss schwer machen. Es hat nichts mit Angular zu tun.ng-controller="MyCtrl as MC"
äquivalent zu setzen$scope.MC = this
sich in der Steuerung - es eine Instanz (diese) von MyCtrl auf dem Rahmen für die Verwendung in der Vorlage definiert über{{ MC.foo }}
Um dieses Verhalten wiederherzustellen (weiß jemand, warum es geändert wurde?), Können Sie Folgendes hinzufügen:
am Ende Ihrer Controller-Funktion (vorausgesetzt, $ scope wurde in diese Controller-Funktion eingefügt).
Dies hat einen schönen Effekt, wenn Sie über ein Controller-Objekt, mit dem Sie untergeordnet werden können, auf den übergeordneten Bereich zugreifen können
require: '^myParentDirective'
quelle
$ scope hat ein anderes 'this' als der Controller 'this'. Wenn Sie also ein console.log (this) in den Controller einfügen, erhalten Sie ein Objekt (controller) und this.addPane () fügt dem Controller-Objekt die addPane-Methode hinzu. Der Bereich $ hat jedoch einen anderen Bereich, und alle Methoden in seinem Bereich müssen von $ scope.methodName () aufgerufen werden.
this.methodName()
Inside Controller bedeutet, Methos innerhalb des Controller-Objekts hinzuzufügen.$scope.functionName()
ist in HTML und drinnenFügen Sie diesen Code in Ihren Editor ein und öffnen Sie die Konsole, um zu sehen ...
quelle