¿Qué es $scope en AngularJS? Tutorial con ejemplo
⚡ Resumen inteligente
$Scope en AngularJS es el objeto integrado que vincula un controlador con su vista. Esta página explica la creación de ámbitos, las funciones de comportamiento, la jerarquía padre-hijo, la diferencia con $rootScope y cómo los ciclos de digestión actualizan las vinculaciones.
¿Qué es $ alcance en AngularJS?
$ alcance en AngularJS es un objeto incorporado que básicamente vincula el "controlador" y la "vista". Se pueden definir variables miembro en el alcance dentro del controlador a las que luego se puede acceder mediante la vista.
Cada controlador en un AngularJS La aplicación recibe su propia instancia de $scope a través de la inyección de dependencias. Todo lo que adjunte a ese objeto se vuelve visible para la plantilla que gobierna el controlador, por lo que $scope se comporta como el modelo de datos compartido que se encuentra entre su JavaLa lógica del script y su marcado HTML.
Considere el siguiente ejemplo:
angular.module('app',[]).controller('HelloWorldCtrl', function($scope) { $scope.message = "Hello World" });
Code Explicación:
- El nombre del módulo es “aplicación”
- El nombre del controlador es “HelloWorldCtrl”.
- El objeto de alcance es el objeto principal que se utiliza para pasar información desde el controlador a la vista.
- Variable miembro agregada al objeto de alcance
⚠️ Advertencia de sintaxis: El .controller() El método toma dos argumentos, el nombre del controlador y la función de fábrica, por lo que se requiere una coma entre ellos. 'HelloWorldCtrl' y function($scope). Omitir la coma provoca un error Uncaught SyntaxError antes de que AngularJS se inicie.
Un único controlador y una única vista solo representan una parte del panorama. Las aplicaciones reales anidan controladores, repiten listas y reutilizan widgets, lo que significa que existen varios ámbitos simultáneamente.
Cómo funcionan la jerarquía de ámbito y la herencia en AngularJS
Cada aplicación AngularJS tiene un único ámbito raíz y puede tener cualquier número de ámbitos secundarios. Las directivas crean esos ámbitos secundarios y los asocian al elemento DOM que decoran, de modo que el árbol de ámbitos refleja la estructura de la página renderizada.
Cuando AngularJS evalúa una expresión como {{siteName}}Primero busca esa propiedad en el ámbito asociado al elemento. Si la propiedad no está presente, la búsqueda se traslada al ámbito padre y continúa ascendiendo hasta llegar al ámbito raíz. JavaLos desarrolladores de scripts conocen este comportamiento como herencia prototípica, y los ámbitos secundarios heredan de sus padres exactamente de esa manera.
El ejemplo que se muestra a continuación anida un controlador dentro de otro para que puedas observar cómo se produce la herencia.
<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 Explicación:
ParentCtrlla definesiteNameen su propio ámbito.ChildCtrlnunca definesiteName, sin embargo, el div interior todavía imprime Guru99 porque la búsqueda se realiza hasta el ámbito principal.lessonExiste únicamente en el ámbito del elemento hijo, por lo que el div padre no puede leerlo.
¿Qué directivas crean un nuevo ámbito?
- ng-controller: crea un ámbito secundario para el elemento en el que se coloca.
- ng-repeat: crea un ámbito secundario por iteración, razón por la cual cada fila puede contener valores diferentes para la misma expresión.
- Directivas personalizadas: puede solicitar un ámbito secundario o un aislar ámbito que deliberadamente no hereda de su padre.
- Directivas de componentes: cualquier cosa registrada con el
.component()El ayudante siempre recibe un ámbito aislado.
Debido a que los ámbitos secundarios se leen de arriba hacia abajo, los desarrolladores a menudo se preguntan dónde se encuentra la parte superior de esa cadena. Ese objeto de nivel superior se llama $rootScope.
$scope vs $rootScope: ¿Cuál es la diferencia?
AngularJS $rootScope es el ámbito de toda la aplicación. Una aplicación solo puede tener un $rootScope y se usa como una variable global. Cada $scope es un ámbito hijo, y $rootScope es el padre en la parte superior del árbol. La siguiente tabla compara los dos objetos.
| Aspecto | Alcance | $rootScope |
|---|---|---|
| Instancias por aplicación | Muchos, uno por controlador o directiva de creación de ámbito. | Exactamente uno |
| Creada por | Directivas como ng-controller y ng-repeat | El inyector durante el arranque de la aplicación |
| Visibilidad | Su propio elemento y todos sus descendientes | Cada ámbito en la aplicación |
| Uso típico | Datos y comportamiento para una vista o una fila de lista. | Valores de toda la aplicación, como un usuario que ha iniciado sesión. |
| Riesgo principal | Los valores se vuelven inalcanzables fuera de la sucursal. | Colisiones de nombres y acoplamiento oculto, como variables globales |
Utilice $rootScope con moderación. Todo lo que se coloque allí existe para toda la aplicación y es legible en todas partes, por lo que un servicio compartido suele ser un lugar más seguro para el estado global. El oficial Referencia de $rootScope Enumera la API completa.
Saber dónde se almacenan los datos es solo la mitad del trabajo. La otra mitad consiste en enseñarle al sistema cómo responder cuando el usuario realiza alguna acción.
Configurar o agregar comportamiento en AngularJS
Para reaccionar a eventos o ejecutar algún tipo de cálculo/procesamiento en la Vista, debemos proporcionar comportamiento al alcance.
Los comportamientos se agregan a los objetos de alcance para responder a eventos específicos que la Vista puede desencadenar. Una vez que el comportamiento está definido en el controlador, la vista puede acceder a él.
Veamos un ejemplo de cómo podemos lograrlo.
<!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 Explicación:
- Estamos creando un comportamiento llamado "nombre completo". Este comportamiento es una función que acepta 2 parámetros (nombre, apellido).
- Luego, el comportamiento devuelve la concatenación de estos 2 parámetros.
- En la vista estamos llamando al comportamiento y pasando 2 valores de “Guru” y “99”, que se pasan como parámetros al comportamiento.
Si el comando se ejecuta correctamente, se mostrará la siguiente salida cuando ejecute su código en el navegador.
Salida:
En el navegador verá una concatenación de ambos valores de Guru & 99 que se transmitieron al comportamiento en el controlador.
Los enlaces como el anterior se actualizan automáticamente, y vale la pena comprender el mecanismo que lo hace posible antes de que una aplicación crezca demasiado.
Por qué son importantes los observadores del alcance y el ciclo de digestión
AngularJS mantiene la vista sincronizada con el ámbito mediante comprobaciones de cambios en lugar de mediante eventos de cambio. Tres API de ámbito impulsan ese proceso:
- $watch: registra un oyente para una expresión. Interpolaciones como
{{fullName}}Registra observadores para ti durante la vinculación de plantillas. - $aplicar: Entra en el contexto de ejecución de AngularJS, evalúa tu código y luego activa un análisis. Solo es necesario dentro de las funciones de devolución de llamada de eventos personalizados o de bibliotecas de terceros, ya que las directivas integradas ya lo invocan.
- $digest: Recorre cada observador en $rootScope y sus hijos, comparando el valor actual con el anterior, y repite hasta que el modelo deja de cambiar.
Debido a que un digest puede ejecutar varias pasadas, las expresiones de vigilancia deben mantenerse económicas. Evite el acceso al DOM dentro de ellas, ya que leer el DOM es órdenes de magnitud más lento que leer un JavaPropiedad del script.
La profundidad de vigilancia también afecta al coste. La vigilancia por referencia es la más rápida y solo se detecta cuando se ha repuesto el valor total. $watchCollection Detecta los elementos añadidos, eliminados o reordenados dentro de una matriz u objeto. La monitorización por valor recorre una estructura anidada en cada operación digest y es la opción más costosa, por lo que conviene usarla al final.




