Na seção "Criar componentes" da página inicial do AngularJS , existe este exemplo:
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);
}
}
Observe como o select
método é adicionado $scope
, mas o addPane
método é adicionado this
. Se eu mudar para $scope.addPane
, o código será quebrado.
A documentação diz que de fato há uma diferença, mas não menciona qual é a diferença:
As versões anteriores do Angular (pré 1.0 RC) permitiam o uso
this
intercambiável com o$scope
método, mas esse não é mais o caso. Dentro dos métodos definidos no escopothis
e$scope
são intercambiáveis (conjuntos angularesthis
para$scope
), mas não dentro do construtor do controlador.
Como funciona this
e $scope
funciona nos controladores AngularJS?
angularjs
angularjs-scope
this
Alexei Boronine
fonte
fonte
Respostas:
Resposta curta :
this
this
é o controlador.$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
$scope
objeto associado .$scope
.$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, deng-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 é criadaele é 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á:
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 painelrequire
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:E o
ParentCtrl
(Solely) temClicar 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 aoParentCtrl
.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 aoChildCtrl
. Então, aqui,this
está definido comoChildCtrl
's$scope
. Dentro do método,$scope
ainda está oParentCtrl
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.fonte
A razão pela qual 'addPane' é atribuída a isso é por causa da
<pane>
diretiva.A
pane
diretiva doesrequire: '^tabs'
, que coloca o objeto do controlador de guias de uma diretiva pai, na função link.addPane
é atribuído parathis
que apane
função de link possa vê-lo. Então, napane
função de link,addPane
é apenas uma propriedade dotabs
controlador e são apenas tabsControllerObject.addPane. Portanto, a função de vinculação da diretiva do painel pode acessar o objeto do controlador de guias e, portanto, acessar o método addPane.Espero que minha explicação seja clara o suficiente .. é meio difícil de explicar.
fonte
Acabei de ler uma explicação bastante interessante sobre a diferença entre os dois, e uma preferência crescente por anexar modelos ao controlador e, aliás, o controlador para vincular modelos à visualização. http://toddmotto.com/digging-into-angulars-controller-as-syntax/ é o artigo.
Ele não menciona isso, mas ao definir diretivas, se você precisar compartilhar algo entre várias diretivas e não desejar um serviço (há casos legítimos em que os serviços são um aborrecimento), anexe os dados ao controlador da diretiva pai.
O
$scope
serviço fornece muitas coisas úteis,$watch
sendo as mais óbvias, mas se tudo o que você precisa para vincular dados à exibição, usar o controlador simples e 'controller as' no modelo é bom e sem dúvida preferível.fonte
Eu recomendo que você leia a seguinte postagem: AngularJS: "Controller as" ou "$ scope"?
Ele descreve muito bem as vantagens de usar "Controller as" para expor variáveis sobre "$ scope".
Sei que você perguntou especificamente sobre métodos e não variáveis, mas acho que é melhor seguir uma técnica e ser consistente com ela.
Então, na minha opinião, devido ao problema de variáveis discutido no post, é melhor usar a técnica "Controller as" e também aplicá-la aos métodos.
fonte
Neste curso ( https://www.codeschool.com/courses/shaping-up-with-angular-js ), eles explicam como usar "this" e muitas outras coisas.
Se você adicionar método ao controlador através do método "this", precisará chamá-lo na exibição com o nome do controlador "dot" como sua propriedade ou método.
Por exemplo, usando seu controlador na visualização, você pode ter um código como este:
fonte
$scope
, então obrigado por mencioná-lo.as
e,this
portanto, como ele pode ajudar a explicar a diferença?$scope
nunca foi mencionado, aprendi a usar apenasthis
nos controladores. O problema é que, quando você começa a lidar com promessas em seu controlador, tem muitos problemas de referênciathis
e precisa começar a fazer coisas comovar me = this
referenciar o modelo athis
partir da função de retorno de promessa. Por isso, ainda estou muito confuso sobre qual método devo usar$scope
outhis
.var me = this
ou.bind(this)
sempre que fizer Promessas, ou outras coisas pesadas. Não tem nada a ver com angular.ng-controller="MyCtrl as MC"
equivale a colocar$scope.MC = this
no próprio controlador - ele define uma instância (esta) do MyCtrl no escopo para uso no modelo via #{{ MC.foo }}
Para recuperar esse comportamento (alguém sabe por que ele foi alterado?), Você pode adicionar:
no final da função do seu controlador (desde que $ scope tenha sido injetado nessa função do controlador).
Isso tem um bom efeito de ter acesso ao escopo pai via objeto do controlador com o qual você pode entrar em filho
require: '^myParentDirective'
fonte
$ scope tem um 'this' diferente do controller 'this'.Thus, se você colocar um console.log (this) dentro do controller, ele fornece um objeto (controller) e this.addPane () adiciona o método addPane ao controller Object. Mas o $ scope tem escopo diferente e todo método em seu escopo precisa ser acessado por $ scope.methodName ().
this.methodName()
controlador interno significa adicionar methos ao objeto controlador.$scope.functionName()
está em HTML e dentroCole este código no seu editor e abra o console para ver ...
fonte