O que é `$scope` no AngularJS? Tutorial com exemplo.
⚡ Resumo Inteligente
Em AngularJS, o `$Scope` é o objeto nativo que vincula um controlador à sua visualização. Esta página explica a criação de escopos, funções de comportamento, hierarquia de pai e filho, a diferença em relação ao `$rootScope` e como os ciclos de digestão atualizam as vinculações.
O que é $scope no AngularJS?
$ escopo em AngularJS é um objeto embutido que basicamente liga o “controlador” e a “visualização”. Pode-se definir variáveis de membro no escopo do controlador que podem então ser acessadas pela visualização.
Cada controlador em um AngularJS A aplicação recebe sua própria instância de `$scope` por meio de injeção de dependência. Tudo o que você anexar a esse objeto se torna visível para o template que o controlador gerencia, portanto, `$scope` se comporta como o modelo de dados compartilhado que fica entre sua aplicação e o template. JavaA lógica do script e sua marcação HTML.
Considere o exemplo abaixo:
angular.module('app',[]).controller('HelloWorldCtrl', function($scope) { $scope.message = "Hello World" });
Code Explicação:
- O nome do módulo é “app”
- O nome do controlador é “HelloWorldCtrl”.
- O objeto de escopo é o objeto principal usado para passar informações do controlador para a visualização.
- Variável de membro adicionada ao objeto de escopo
⚠️ Aviso de sintaxe: O .controller() O método recebe dois argumentos, o nome do controlador e a função de fábrica, portanto, é necessária uma vírgula entre eles. 'HelloWorldCtrl' e function($scope)Omitir a vírgula causa um erro. Uncaught SyntaxError antes mesmo do AngularJS inicializar.
Um único controlador e uma única visualização representam apenas metade da solução. Aplicações reais aninham controladores, repetem listas e reutilizam widgets, o que significa que vários escopos coexistem.
Como funcionam a hierarquia de escopo e a herança no AngularJS
Cada aplicação AngularJS possui exatamente um escopo raiz e pode ter qualquer número de escopos filhos. As diretivas criam esses escopos filhos e os associam ao elemento DOM que decoram, de modo que a árvore de escopos espelhe a estrutura da página renderizada.
Quando o AngularJS avalia uma expressão como {{siteName}}Primeiro, ele procura essa propriedade no escopo associado ao elemento. Se a propriedade estiver ausente, a busca passa para o escopo pai e continua subindo até chegar ao escopo raiz. JavaOs desenvolvedores de scripts conhecem esse comportamento como herança prototípica, e os escopos filhos herdam de seus pais exatamente dessa maneira.
O exemplo abaixo aninha um controlador dentro de outro para que você possa observar a herança ocorrer.
<div ng-app="scopeDemo"> <div ng-controller="ParentCtrl"> Parent scope value: {{siteName}} <div ng-controller="ChildCtrl"> Child reads parent value: {{siteName}} Child own value: {{lesson}} </div> </div> </div> <script type="text/javascript"> var app = angular.module("scopeDemo", []); app.controller("ParentCtrl", function($scope) { $scope.siteName = "Guru99"; }); app.controller("ChildCtrl", function($scope) { $scope.lesson = "AngularJS Scope"; }); </script>
Code Explicação:
ParentCtrldefinesiteNameem seu próprio âmbito.ChildCtrlnunca definesiteName, mas a div interna ainda imprime Guru99 Porque a pesquisa percorre o escopo até o escopo pai.lessonEla existe apenas no escopo filho, portanto a div pai não pode lê-la.
Quais diretivas criam um novo escopo?
- ng-controller: Cria um escopo filho para o elemento em que é colocado.
- ng-repeat: Cria um escopo filho por iteração, razão pela qual cada linha pode conter valores diferentes para a mesma expressão.
- Diretivas personalizadas: pode solicitar um endoscópio infantil, ou um isolar escopo que deliberadamente não herda de seu pai.
- Diretivas de componentes: qualquer coisa registrada com o
.component()O auxiliar sempre recebe um escopo isolado.
Como os escopos filhos são lidos de baixo para cima, os desenvolvedores frequentemente se perguntam onde fica o topo dessa cadeia. Esse objeto de nível superior é chamado de `$rootScope`.
$scope vs $rootScope: Qual é a diferença?
O AngularJS $rootScope é o escopo de toda a aplicação. Uma aplicação só pode ter um `$rootScope`, que é usado como uma variável global. Cada `$scope` é um escopo filho, e `$rootScope` é o escopo pai no topo da árvore. A tabela abaixo compara os dois objetos.
| Aspecto | $escopo | $rootScope |
|---|---|---|
| Instâncias por aplicação | Vários, um por controlador ou diretiva de criação de escopo. | Exatamente um |
| Criado por | Diretivas como ng-controller e ng-repeat | O injetor durante a inicialização do aplicativo |
| Visibilidade | Seu próprio elemento e todos os seus descendentes | Cada escopo no aplicativo |
| Uso típico | Dados e comportamento para uma visualização ou uma linha de lista. | Valores globais da aplicação, como um usuário conectado. |
| risco principal | Os valores tornam-se inacessíveis fora do ramo. | Conflitos de nomes e acoplamento oculto, como variáveis globais. |
Use `$rootScope` com moderação. Qualquer coisa colocada ali é válida para toda a aplicação e pode ser lida em qualquer lugar, então um serviço compartilhado geralmente é um local mais seguro para o estado global. O oficial Referência $rootScope Lista a API completa.
Saber onde os dados estão armazenados é metade do trabalho. A outra metade é ensinar o escopo a como responder quando o usuário realiza alguma ação.
Configurar ou adicionar comportamento no AngularJS
Para reagir a eventos ou executar algum tipo de computação/processamento na View, devemos fornecer comportamento ao escopo.
Os comportamentos são adicionados aos objetos de escopo para responder a eventos específicos que podem ser acionados pela Visualização. Uma vez definido o comportamento no controlador, ele pode ser acessado pela visualização.
Vejamos um exemplo de como podemos conseguir isso.
<!DOCTYPE html> <html lang="en"> <head> <meta chrset="UTF 8"> <title>Guru99</title> </head> <body ng-app="DemoApp"> <h1> Guru99 Global Event</h1> <script src="https://code.angularjs.org/1.6.9/angular.js"></script> <div ng-controller="DemoController"> {{fullName("Guru","99")}} </div> <script type="text/javascript"> var app = angular.module("DemoApp", []); app.controller("DemoController", function($scope) { $scope.fullName=function(firstName,lastname){ return firstName + lastname; } } ); </script> </body> </html>
Code Explicação:
- Estamos criando um comportamento chamado “fullName”. Este comportamento é uma função que aceita 2 parâmetros (primeiro nome, sobrenome).
- O comportamento então retorna a concatenação desses 2 parâmetros.
- Na visualização, estamos chamando o comportamento e passando 2 valores de “Gurue “99”, que são passados como parâmetros para o comportamento.
Se o comando for executado com sucesso, a seguinte saída será mostrada quando você executar seu código no navegador.
Saída:
No navegador, você verá uma concatenação dos dois valores de Guru & 99 que foram repassados ao comportamento no controlador.
Associações como a acima são atualizadas automaticamente, e vale a pena entender o mecanismo que torna isso possível antes que um aplicativo cresça muito.
Por que os observadores de escopo e o ciclo de digestão são importantes
O AngularJS mantém a visualização sincronizada com o escopo por meio de verificações de alterações (dirty checking), em vez de eventos de mudança (change events). Três APIs de escopo conduzem esse processo:
- $watch: Registra um ouvinte para uma expressão. Interpolações como
{{fullName}}Registre observadores para você durante a vinculação do modelo. - Aplicar: Entra no contexto de execução do AngularJS, avalia seu código e, em seguida, dispara um digest. É necessário apenas dentro de callbacks de eventos personalizados ou callbacks de bibliotecas de terceiros, pois as diretivas integradas já o chamam.
- $digest: Percorre todos os observadores em $rootScope e seus filhos, comparando o valor atual com o anterior, e repete até que o modelo pare de mudar.
Como um processo de digestão pode executar várias passagens, as expressões de observação devem ser executadas de forma eficiente. Evite acessar o DOM dentro delas, pois a leitura do DOM é ordens de magnitude mais lenta do que a leitura de um objeto. JavaPropriedade do script.
A profundidade de observação também afeta o custo. A observação por referência é a mais rápida e só percebe quando o valor total é substituído. $watchCollection O recurso de observação registra itens adicionados, removidos ou reordenados dentro de um array ou objeto. A observação por valor percorre uma estrutura aninhada a cada resumo e é a opção mais custosa, portanto, utilize-a por último.




