Escopo e rootScope em AngularJS
- 24-07-2022
- Toanngo92
- 0 Comments
Em artigos anteriores, entendemos temporariamente a estrutura MVC do AngularJS:
- Visualizar: dados de exibição HTML
- Modelo: dados para trabalhar com a visualização atual
- Controlador: fluxo lógico escrito em funções angularJS, usado para adicionar, editar, excluir dados
$scope é um objeto (objeto) responsável pela comunicação de dados entre o controller e a view da aplicação, podemos entendê-lo como uma ponte, quando a variável $scope muda, os dados no controller e na view são atualizados. Será feito em forma de expressão, ou seja, no modelo que será declarado de acordo com as especificações, o objeto de escopo passará a ação (função) ou dado correspondente e podemos passar eventos por meio desse objeto.
Scopes fornece as mesmas expressões que os motores de template de hoje, por exemplo para mostrar o nome de usuário vamos declará-lo como {{username}} e no controller só precisamos atribuir $scope.username = 'toanngo92' o objeto Isso vai levar uma chave nome de usuário nomeado e atribua-o à visualização {{username}}.
Mục lục
Escopo de $scope
Em uma aplicação AngularJS, podemos ter muitos Controllers, muitos $scopes diferentes. Voltando ao exemplo abaixo:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Example Controller</title> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script> </head> <body> <div ng-app="examController"> <div ng-controller="headerController"> {{name}} - {{data}} </div> <div ng-controller="mainController"> {{name}} - {{data}} </div> <div ng-controller="footerController"> {{name}} - {{data}} </div> </div> <script> var app = angular.module('examController', []); app.controller('headerController', function($scope){ $scope.name = "This is header"; }); app.controller('mainController', function($scope){ $scope.name = "This is main"; $scope.data = "main data"; }); app.controller('footerController', function($scope){ $scope.name = "This is footer"; }); </script> </body> </html>
Vemos nas views vinculadas ao controller correspondente que o valor {{data}} é diferente, mas cada controller, a propriedade data na variável em cada controller é diferente. Isso prova que o escopo da variável $scope está apenas no controlador correspondente.
$rootScope e a hierarquia de $scope
Exemplo 1:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="angular.min.js"></script> <!-- <script src="angular-route.min.js"></script> --> </head> <body ng-app="toanApp"> <div >Data rootscope: {{name}}</div> <div ng-controller="indexController"> <input ng-model="name" value=""/> <p> Data scope {{name}}</p> <button ng-click="changename()" >click</button> </div> <script> var app = angular.module("toanApp",[]); app.run(function($rootScope){ $rootScope.name = "root scope"; }); app.controller( "indexController", function($scope){ // console.log(languages); $scope.name = "controller scope"; $scope.changename = function(e){ $scope.name = "test"; } } ); </script> </body> </html>
Resultado ao imprimir e interagir com a entrada
Com o exemplo acima, vemos que usamos uma div e chamamos o nome do modelo para a view, mas esse modelo não pertence a nenhum controller, entendemos abaixo da camada de script, através do método app.run() , inicializamos um modelo global chamado name, portanto, mesmo que não esteja em nenhum controlador, ainda podemos representar o nome da variável. e para o nome do modelo na estrutura div dentro do indexController, vemos ao atualizar os dados, o modelo no controlador muda, mas não tem nada a ver com o modelo externo, faz sentido, 2 nomes de modelo estão em $scope e $rootScope , embora tenham o mesmo nome , eles não estão relacionados na natureza
Exemplo #2 :
Agora vamos alterar um pouco a sintaxe do código AngularJS da seguinte forma:
Neste exemplo, a principal diferença é que o primeiro Controlador JS possui um parâmetro $rootScope e o segundo Controlador não manipula nada. Execute-o, você verá a seguinte interface:
Então obviamente o código acima não passa o valor para $scope nos dois controllers, mas a view ainda tem? Isso porque a variável $rootScope. Isso significa que quando o aplicativo for executado, haverá um $rootScope criado automaticamente, $rootScope é o nível superior, portanto, cobrirá todos os $scopes dentro dele, não é o mesmo que $scope, que afeta apenas o escopo do controlador .
Considere o exemplo abaixo:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Example Controller</title> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script> </head> <body> <div ng-app="examRootScope"> <div ng-controller="headerController"> {{name}} - {{data}} {{data_global}} </div> <div ng-controller="mainController"> {{name}} - {{data}} </div> <div ng-controller="footerController"> {{name}} - {{data}} </div> </div> <script> var app = angular.module('examRootScope', []); app.controller('headerController', function($scope,$rootScope){ $scope.name = "This is header"; $scope.data= "header data scope"; $rootScope.data = "header data root scope"; }); app.controller('mainController', function($scope){ $scope.name = "This is main"; $scope.data = "main data"; }); app.controller('footerController', function($scope,$rootScope){ $scope.name = "This is footer"; $scope.data = "footer data scope"; $rootScope.data_global = "thuoc tinh dung chung"; }); </script> </body> </html>
Imprima os resultados na tela:
Adicionando mais algumas informações no exemplo acima, há 2 pontos a serem observados:
- No headerController, as duas propriedades $scope.data e $rootScope.data têm o mesmo nome (data), mas ao imprimir a view com uma expressão, o valor será retirado da propriedade data do berço $scope, comprovando se caso o modelo tenha o mesmo nome, $scope terá precedência sobre $rootScope
- No footerController, existe uma propriedade chamada data_global que eu mesmo configurei, mas na camada de visualização associada ao headerController, chamei intencionalmente esse modelo data_global, mas as visualizações ainda são reconhecidas, isso prova que os dados em $ rootScope são globais (pode ser usado para compartilhar ou passar dados entre controladores)
Escopo aninhado (escopo aninhado)
No angularJS, temos o conceito de controladores aninhados, escopos aninhados de forma semelhante, com essa situação precisa ter muito cuidado pois haverá muitas situações em que será impossível distinguir qual escopo está usando. Considere o exemplo abaixo:
<!DOCTYPE html> <html lang="en" ng-app="myApp"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script> </head> <body ng-controller="parentController"> What controller am I? {{parentVariable}} <div ng-controller="childController"> What controller am I? {{childVariable}} {{parentVariable}} <button ng-click="childFunction()"> Click me to override! </button> </div> </body> <script> var app = angular.module('myApp', []); app.controller('parentController', function ($scope) { $scope.parentVariable = "I'm the parent"; }); app.controller('childController', function ($scope) { $scope.childVariable = "I'm the child"; $scope.childFunction = function () { $scope.parentVariable = "Parent changed!"; console.log($scope); }; }); </script> </html>
Resultado ao executar o teste e clicar no botão de substituição:
O problema aqui, ao registrar a variável $scope, os dados parentVariable foram alterados, mas o parentVariable no parentController não é atualizado, esse problema será realmente confuso e inconveniente no processo de codificação, então conselho Para você, você deve nomear as variáveis com clareza , se você precisar usar controladores aninhados, deverá aprender a estrutura com cuidado para evitar erros inesperados.
Além disso, se falarmos sobre escopo, haverá muitos problemas, mas em termos de abordagem, esses conceitos são as coisas que precisamos entender antes de fazer uma aplicação real com angularjs.