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.

  • 🔗 Função de ligação: O parâmetro `$scope` transporta variáveis ​​de membro de um controlador para a visualização, permitindo que os templates renderizem os dados sem manipular o DOM diretamente.
  • ⚙️ Funções comportamentais: Anexe funções ao $scope quando a visualização precisar reagir a cliques, alterações de entrada ou outros eventos do usuário.
  • ???? Hierarquia de escopo: Diretivas como ng-controller e ng-repeat criam escopos filhos que espelham a árvore DOM da aplicação.
  • ???? Alcance do escopo raiz: Existe um `$rootScope` por aplicação, que se comporta como um objeto global que todos os escopos filhos podem ler.
  • 🔍 Ciclo digestivo: `$watch` registra os ouvintes, `$apply` entra no contexto de execução do AngularJS e `$digest` compara os valores até que o modelo se estabilize.
  • 🚀 Hábito de desempenho: Mantenha as expressões de observação simples, evite acessar o DOM dentro delas e chame `$destroy` nos escopos que não forem mais necessários.

O que é `$Scope` no AngularJS?

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:

$ escopo em AngularJS

angular.module('app',[]).controller('HelloWorldCtrl',
	function($scope)
	{
		$scope.message = "Hello World"
	});

Code Explicação:

  1. O nome do módulo é “app”
  2. O nome do controlador é “HelloWorldCtrl”.
  3. O objeto de escopo é o objeto principal usado para passar informações do controlador para a visualização.
  4. 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:

  1. ParentCtrl define siteName em seu próprio âmbito.
  2. ChildCtrl nunca define siteName, mas a div interna ainda imprime Guru99 Porque a pesquisa percorre o escopo até o escopo pai.
  3. lesson Ela 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.

Configurando ou adicionando comportamento

<!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:

  1. Estamos criando um comportamento chamado “fullName”. Este comportamento é uma função que aceita 2 parâmetros (primeiro nome, sobrenome).
  2. O comportamento então retorna a concatenação desses 2 parâmetros.
  3. 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:

Configurando ou adicionando comportamento

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.

Perguntas Frequentes

Um escopo isolado não herda prototipicamente de seu pai. Diretivas de componentes construídas com o auxiliar `.component()` sempre recebem um, o que mantém os widgets reutilizáveis ​​independentes do controlador circundante e impede leituras acidentais de propriedades do pai.

O comando `$emit` envia um evento de escopo para cima, através dos escopos pai, em direção a `$rootScope`, enquanto o comando `$broadcast` o envia para baixo, para todos os escopos filhos. Ambos são recebidos com `$on`. Use `$broadcast` com moderação, pois ele visita todos os escopos descendentes.

Chame `scope.$destroy()` assim que um escopo filho não for mais necessário. Isso interrompe a propagação do digest para o escopo e permite que o coletor de lixo recupere seus modelos. Remova também os observadores manuais, chamando a função retornada por `$watch`.

Assistentes como Copiloto do GitHub Eles geram código boilerplate de escopo rapidamente, mas ainda cometem erros, como a falta de uma vírgula no registro de um controlador. Verifique cada trecho gerado em relação ao código oficial. Documentação de escopo do AngularJS.

Os assistentes de IA mapeiam as propriedades do `$scope` para os campos da classe do componente e reescrevem a lógica do `$watch` como sinais ou fluxos RxJS. Combine-os com o oficial Angular Documentação e execução de testes unitários, pois as conversões geradas frequentemente omitem pesquisas de escopo herdado.

Resuma esta postagem com: