"Como funciona this
e $scope
funciona nos controladores AngularJS?"
Resposta curta :
this
- Quando a função construtora do controlador é chamada,
this
é o controlador.
- Quando uma função definida em um
$scope
objeto é chamada, this
é o "escopo em vigor quando a função foi chamada". Isso pode (ou não!) Ser o $scope
que a função está definida. Portanto, dentro da função, this
e $scope
pode não ser o mesmo.
$scope
- Todo controlador tem um
$scope
objeto associado .
- Uma função do controlador (construtor) é responsável por definir propriedades do modelo e funções / comportamento em seus associados
$scope
.
- Somente métodos definidos nesse
$scope
objeto (e objetos de escopo pai, se houver herança prototípica em jogo) são acessíveis a partir do HTML / view. Por exemplo, de ng-click
, filtros, etc.
Resposta longa :
Uma função do controlador é uma função do construtor JavaScript. Quando a função construtora é executada (por exemplo, quando uma exibição é carregada), this
(ou seja, o "contexto da função") é definido como o objeto do controlador. Portanto, na função construtora do controlador "tabs", quando a função addPane é criada
this.addPane = function(pane) { ... }
ele é criado no objeto do controlador, não no $ scope. As visualizações não podem ver a função addPane - elas só têm acesso às funções definidas no $ scope. Em outras palavras, no HTML, isso não funcionará:
<a ng-click="addPane(newPane)">won't work</a>
Após a função construtora do controlador "tabs" ser executada, temos o seguinte:
A linha preta tracejada indica herança prototípica - um escopo isolado herda prototipicamente do Scope . (Não herda prototipicamente do escopo em vigor onde a diretiva foi encontrada no HTML.)
Agora, a função de link da diretiva de painel deseja se comunicar com a diretiva de guias (o que realmente significa que precisa afetar as guias de isolar o escopo $ de alguma forma). Eventos podem ser usados, mas outro mecanismo é ter a diretiva de painel require
no controlador de guias. (Parece não haver mecanismo para a diretiva de painel require
nas guias $ scope.)
Então, isso levanta a questão: se apenas temos acesso ao controlador de guias, como obtemos acesso às guias isolamos $ scope (que é o que realmente queremos)?
Bem, a linha pontilhada vermelha é a resposta. O "escopo" da função addPane () (estou me referindo ao escopo / fechamento da função do JavaScript aqui) fornece à função acesso às guias que isolam $ scope. Ou seja, addPane () tem acesso às "guias IsolateScope" no diagrama acima devido a um fechamento criado quando addPane () foi definido. (Se definíssemos addPane () no objeto tabs $ scope, a diretiva painel não teria acesso a essa função e, portanto, não teria como se comunicar com o tabs $ scope.
Para responder à outra parte da sua pergunta how does $scope work in controllers?
:
Nas funções definidas em $ scope, this
é definido como "o $ scope em vigor onde / quando a função foi chamada". Suponha que tenhamos o seguinte 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>
E o ParentCtrl
(Solely) tem
$scope.logThisAndScope = function() {
console.log(this, $scope)
}
Clicar no primeiro link mostrará isso this
e $scope
é o mesmo, já que " o escopo em vigor quando a função foi chamada " é o escopo associado ao ParentCtrl
.
Ao clicar no segundo link irá revelar this
e $scope
são não o mesmo, uma vez que " o escopo em vigor quando a função foi chamada " é o escopo associado ao ChildCtrl
. Então, aqui, this
está definido como ChildCtrl
's $scope
. Dentro do método, $scope
ainda está o ParentCtrl
escopo de $.
Violino
Tento não usar this
dentro de uma função definida no $ scope, pois fica confuso qual $ scope está sendo afetado, especialmente considerando que as diretivas ng-repeat, ng-include, ng-switch e diretivas podem criar seus próprios escopos filhos.