"¿Cómo funciona this
y $scope
funciona en los controladores AngularJS?"
Respuesta corta :
this
- Cuando se llama a la función constructora del controlador,
this
es el controlador.
- Cuando
$scope
se llama a una función definida en un objeto, this
es el "alcance vigente cuando se llamó a la función". Esto puede (¡o no!) Ser en el $scope
que se define la función. Entonces, dentro de la función, this
y $scope
puede no ser lo mismo.
$scope
- Cada controlador tiene un
$scope
objeto asociado .
- Una función de controlador (constructor) es responsable de establecer las propiedades del modelo y las funciones / comportamiento en sus asociados
$scope
.
- Solo los métodos definidos en este
$scope
objeto (y los objetos del ámbito principal, si la herencia prototípica está en juego) son accesibles desde la vista / HTML. Por ejemplo, desde ng-click
, filtros, etc.
Respuesta larga :
Una función de controlador es una función constructora de JavaScript. Cuando se ejecuta la función del constructor (por ejemplo, cuando se carga una vista), this
(es decir, el "contexto de la función") se establece en el objeto controlador. Entonces, en la función del constructor del controlador "pestañas", cuando se crea la función addPane
this.addPane = function(pane) { ... }
se crea en el objeto controlador, no en $ scope. Las vistas no pueden ver la función addPane: solo tienen acceso a las funciones definidas en $ scope. En otras palabras, en el HTML, esto no funcionará:
<a ng-click="addPane(newPane)">won't work</a>
Después de que se ejecuta la función del constructor del controlador "pestañas", tenemos lo siguiente:
La línea negra discontinua indica herencia prototípica: un alcance aislado hereda prototípicamente de Scope . (No hereda prototípicamente del alcance en efecto donde se encontró la directiva en el HTML).
Ahora, la función de enlace de la directiva de panel quiere comunicarse con la directiva de pestañas (lo que realmente significa que debe afectar a las pestañas aislar $ scope de alguna manera). Se podrían usar eventos, pero otro mecanismo es hacer que el panel dirija require
el controlador de pestañas. (Parece que no hay ningún mecanismo para la directiva de panel para require
las pestañas $ scope).
Entonces, esto plantea la pregunta: si solo tenemos acceso al controlador de pestañas, ¿cómo podemos acceder a las pestañas aislar $ scope (que es lo que realmente queremos)?
Bueno, la línea punteada roja es la respuesta. El "alcance" de la función addPane () (me refiero al alcance / cierres de la función de JavaScript aquí) le da a la función acceso a las pestañas aislar $ scope. Es decir, addPane () tiene acceso a las "pestañas IsolateScope" en el diagrama anterior debido a un cierre que se creó cuando se definió addPane (). (Si en su lugar definimos addPane () en el objeto de pestañas $ scope, la directiva de panel no tendría acceso a esta función y, por lo tanto, no tendría forma de comunicarse con las pestañas $ scope).
Para responder la otra parte de su pregunta how does $scope work in controllers?
:
Dentro de las funciones definidas en $ scope, this
se establece en "el alcance de $ vigente donde / cuando se llamó a la función". Supongamos que tenemos el siguiente HTML:
<div ng-controller="ParentCtrl">
<a ng-click="logThisAndScope()">log "this" and $scope</a> - parent scope
<div ng-controller="ChildCtrl">
<a ng-click="logThisAndScope()">log "this" and $scope</a> - child scope
</div>
</div>
Y el ParentCtrl
(Solamente) tiene
$scope.logThisAndScope = function() {
console.log(this, $scope)
}
Al hacer clic en el primer enlace se mostrará eso this
y $scope
son lo mismo, ya que " el alcance en vigor cuando se llamó a la función " es el alcance asociado con el ParentCtrl
.
Al hacer clic en el segundo enlace se revelará this
y no$scope
es lo mismo, ya que " el alcance en vigor cuando se llamó a la función " es el alcance asociado con el ChildCtrl
. Así que aquí, this
se establece en ChildCtrl
's $scope
. Dentro del método, $scope
sigue siendo el ParentCtrl
alcance de $.
Violín
Intento no usar this
dentro de una función definida en $ scope, ya que se vuelve confuso qué $ scope está siendo afectado, especialmente teniendo en cuenta que ng-repeat, ng-include, ng-switch y directivas pueden crear sus propios ámbitos secundarios.