1. ¿Qué es el alcance?
Alcance (http://code.angularjs.org/1.0.2/docs/api/ng.$rootscope.scope) es un objeto que apunta al modelo de aplicación. También es el contexto de ejecución de la expresión (http://www.cnblogs.com/lclao/archive/2012/09/16/2687162.html). El alcance se coloca en una jerarquía de estructuras DOM similar a la de la aplicación. El alcance puede monitorear los eventos de expresión y propagación de la expresión y propagación.
2. Las características del alcance
3. Alcance como modelo de datos (alcance como modelo de datos)
El alcance es el enlace entre el controlador de aplicación y la vista. En la etapa de la vinculación de la plantilla (http://www.cnblogs.com/lclao/archive/2012/09/04/2669802.html), directive (http://www.cnblogs.com/lclao/archive/2012/09/267190.html) alcance. $ Watch permite que la Directiva conocer los cambios en los atributos, por lo que la Directiva convierte el valor actualizado en el DOM.
Tanto los controladores como las directivas hacen referencia al alcance, pero no entre sí. Esta disposición separa el controlador de la Directiva y DOM. Este es un lugar importante porque aísla el controlador de la vista, mejorando en gran medida la historia de prueba de las aplicaciones.
<! DocType html> <html lang = "zh-cn" ng-app> <head> <meta charset = "utf-8"> <title> data-model </title> <style type = "text/css"> .ng-cloak {visualización: ninguno; } </style> </head> <body> <div ng-controller = "mycontroller"> su nombre: <input type = "text" ng-model = "username"/> <button ng-click = "sayhello ()"> bienvenido </botón> <hr/> {{saludo}}} </div> <cript src = "../ angular-1.0.0.js". type = "text/javaScript"> </script> <script type = "text/javaScript"> function myController ($ scope) {$ scope.username = "my pequeño dada"; $ scope.sayhello = function () {$ scope.greeting = "hola ~" + $ scope.username + "!"; }; } </script> </body> </html>En el ejemplo anterior podemos notar que MyController asigna el atributo del nombre de usuario en alcance con "My Little Dada". Luego, el alcance notifica la entrada para la asignación y el valor previo del valor del nombre de usuario en la entrada. Esto muestra cómo el controlador puede escribir datos en el alcance.
Del mismo modo, el controlador puede conectar el comportamiento al alcance, al igual que el método Sayhello que se activa cuando el usuario hace clic en el botón "Bienvenido". El método Sayhello puede leer el atributo de nombre de usuario o crear un atributo de saludo. Esto muestra que cuando están vinculados a un control de entrada HTML, las propiedades en el alcance se actualizan automáticamente.
Lógicamente, mostrar {{saludo}} implica los siguientes dos puntos:
Busque el alcance del nodo DOM de la plantilla que define la expresión {{Saludo}}. En este ejemplo, este alcance es el mismo que el alcance que pasó al MyController. (Discutiremos la jerarquía del alcance más tarde)
La expresión de saludo se evalúa a través del alcance recuperado anteriormente, y el resultado se usa como el valor del texto que encierra el elemento DOM.
Podemos pensar que el alcance y sus propias propiedades pueden usarse como datos para representar vistas. El alcance es la única fuente de verdad para todas las cosas relacionadas.
Desde la perspectiva de prueba, la separación del controlador y la vista está encantada, ya que nos permite (centrarnos) en el comportamiento de prueba sin la interferencia de los detalles de representación.
it ('debería decir hola', function () {var scopemock = {}; var cntl = new MyController (scopemock); // afirman que el nombre de usuario está prefillado en la esperanza (scopemock.username) .Toequal ('world'); // que leemos el nombre de usuario y saluda scopemock.username = 'angular'; scopemock; esperar (scopemock.greeting) .toequal ('¡Hola angular!');});4. Jerarquías de alcance (jerarquías de alcance)
Cada aplicación angular tiene y solo un alcance de raíz, pero puede tener múltiples ámbitos infantiles.
Una aplicación puede tener múltiples ámbitos infantiles, porque algunas directivas crearán nuevos ámbitos infantiles (consulte la documentación de la Directiva para ver qué directivas pueden crear nuevos ámbitos, como Ng-Rpeat). Cuando se crea el nuevo alcance, se agregarán al alcance principal como un alcance infantil. De esta manera, se crea una estructura de árbol similar al DOM que están unidas.
Cuando Angular evalúa {{nombre de usuario}}, primero analiza la propiedad del nombre de usuario del alcance asociado con el elemento actual. Si no se encuentra una propiedad correspondiente, buscará el alcance de los padres hasta que alcance el alcance de la raíz. En JavaScript, este comportamiento se llama "herencia prototipo", y el alcance infantil generalmente se hereda de sus padres.
Este ejemplo muestra el alcance (qué es) y la herencia prototipo de propiedades en la aplicación.
<! DocType html> <html lang = "zh-cn" ng-app> <head> <meta charset = "utf-8"> <title> escopo-hierarquías </title> <style type = "text/css"> .ng-cloak {Display: Ninguno; } .ng-scope {border: 1px Red Red; } </style> </head> <body> <div ng-controller = "mycontroller"> gerente: {{empleado.name}} [{{departamento}}] <br/> informe: <ul> <li ng-epeat = "Empleado en empleado.Reports"> {{Empleado.name} [{{{{{{{{{{{{{{{{{{{ <hr/> {{saludo}} </div> <script src = "../ angular-1.0.1.js" type = "text/javaScript"> </script> <script type = "text/javaScript"> function myController ($ scope) {$ scope.department = "una unidad cierta"; $ Scope.Employee = {name: "my Little Dada", informa: [{nombre: "lclao"}, {nombre: "Who^o^"}]}; } </script> </body> </html>Tenga en cuenta que Angular coloca automáticamente la clase Ng-Scope en elementos que se adhieren al alcance. <Syle> se define en el ejemplo anterior, resaltando el rango del nuevo alcance a través de la línea punteada roja. Debido a que el repetidor evalúa la expresión {{Employee.name}}, el alcance infantil es necesario, pero dependiendo de qué alcance se evalúa la expresión, diferentes alcances tienen resultados diferentes. Del mismo modo, el valor de {{departamento}} se hereda del prototipo en el alcance de la raíz. Solo cuando está, se puede definir el atributo del departamento.
5. Recuperando alcances del DOM (recuperar el alcance del DOM)
El alcance se adjunta al DOM como el atributo de datos de alcance y se puede utilizar para recuperar para fines de depuración. (Es imposible recuperar el alcance de esta manera en la aplicación). La ubicación del alcance de la raíz unido al DOM se define por la ubicación de la Directiva NG-APP. Por lo general, NG-APP se coloca en el elemento <html>, pero también se puede colocar en otros elementos, por ejemplo, solo una parte de la vista debe ser controlada por Angular.
Ver el alcance en el depurador:
1. En el navegador, haga clic con el botón derecho en el elemento que le interesa y seleccione "Ver elemento". Podemos ver que el depurador del navegador destaca los elementos que seleccionamos.
2. El depurador nos permite acceder al elemento seleccionado actualmente a través de la variable $ 0 en la consola.
3. Si desea ver el alcance asociado, podemos ingresar: angular.element ($ 0) .scope () en la consola
6. Propagación de eventos de alcance (propagación del evento de alcance)
El alcance puede propagar eventos de manera similar a los eventos DOM. Los eventos se pueden transmitir (http://code.angularjs.org/1.0.2/docs/api/ng.$rootscope.scope#$broadcast) a Child Scope o emit (http://code.angularjs.org/1.0.2/docs/api/ng.$ rootscope.cope#$emit) para. (Si se escucha el alcance actual, también se ejecutará)
<! DocType html> <html lang = "zh-cn" ng-app> <head> <meta charset = "utf-8"> <title> Scope-event-propagation </title> <style type = "text/css"> .ng-cloak {pantalla: Ninguno; } </style> </head> <body> <div ng-concontroller = "myController"> ROOT SCOPE Count: {{Count}} <ul> <li ng-depeat = "i in [1]" ng-confontroller = "mycontroller"> <button ng-click = "$ emit ('myEvent')" $ emit ("myEvent") ng-click="$broadcast('MyEvent')">$broadcast("MyEvent")</button> <br/> middle scope count:{{count}} <ul> <li ng-repeat="item in [1,2]" ng-controller="MyController"> Leaf scope count:{{count}} </li> </ul> </li> </ul> </div> <script src = "../ angular-1.0.1.js" type = "text/javaScript"> </script> <script type = "text/javaScript"> function myController ($ scope) {$ scope.count = 0; $ Scope. $ on ("myEvent", function () {$ scope.count ++;}); } </script> </body> </html>7. Ciclo de vida del alcance (ciclo de vida del alcance)
En el flujo de evento normal del navegador, cuando el navegador recibe el evento, ejecutará una devolución de llamada JavaScript correspondiente. Una vez que se ejecuta la función de devolución de llamada, el navegador volverá a dibujar el DOM y regresará al estado donde continúa esperando el evento.
Cuando el navegador llama al código JavaScript fuera del entorno de ejecución angular, esto significa que Angular no conoce el cambio del modelo. Para manejar correctamente la modificación del modelo, este comando debe ingresar el entorno de ejecución angular haciendo el método $ aplicado. Solo cuando el modelo cambie en el método $ Aplicar será contado correctamente por Angular. Por ejemplo, una directiva escucha un evento DOM, como Ng-Click, que debe evaluar la expresión en el método $ Aplicar.
Después de evaluar la expresión, el método $ Aplice ejecuta A $ Digest. En la etapa $ Digest, el alcance verifica todas las expresiones escuchadas por $ Watch y compara el valor actual con el valor anterior. La verificación sucia es asíncrona. Esto significa que la declaración de asignación (por ejemplo, $ scope.username = "angular") no causará inmediatamente una notificación de un reloj $, pero la notificación de $ watch se retrasará a la etapa $ digest. Este retraso es necesario porque combina múltiples actualizaciones de modelos en una notificación de vigilancia $, lo que garantiza que no se ejecute otro reloj $ durante el proceso de notificación de vigilancia $. Si A $ Watch cambia el valor del modelo, forzará un aumento de un ciclo $ Digest.
1) Creación (crear alcance)
El alcance raíz es creado por $ inyector (http://code.angularjs.org/1.0.2/docs/api/auto.$injector) durante el proceso de inicio de la aplicación. Durante el proceso de enlace de plantilla, algunas directivas crearán un nuevo alcance infantil.
2) Registro de observador (Registro de registro)
Durante el proceso de enlace de la plantilla, la Directiva registra $ Watch In Alcance. Estos relojes se utilizarán como el valor de propagar el modelo al DOM.
3) mutación modelo (cambios en el modelo)
Para que los cambios se detecten correctamente, necesitamos envolverlos en el alcance. $ Aplicar. (La API angular lo ha hecho implícitamente, por lo que cuando se realiza un trabajo sincrónico en el controlador o trabajo asincrónico con $ HTTP o $ Tiempo de espera, no se requiere una llamada adicional de Aplicar)).
4) Observación de mutación (monitoreo de cambios)
Al final de $ Aplicar, Angular ejecutará un ciclo $ Digest en el alcance de la raíz, que se propagará a todos los ámbitos infantiles. En el ciclo $ Digest, todas las expresiones o funciones registradas con $ reloj se verificarán para determinar si el modelo ha cambiado. Si se produce el cambio, se llamará al oyente de vigilancia $ correspondiente.
5) Destrucción del alcance (destrucción del alcance)
Cuando el alcance infantil ya no es necesario, es responsabilidad del productor de alcance infantil destruirlos a través del alcance. $ Destroy () API. Esto detendrá la propagación de llamadas $ digest en el alcance infantil, de modo que la memoria utilizada por el modelo de alcance infantil puede ser reciclado por GC (recolector de basura).
1. Scopes and Directives
Durante la fase de compilación, el compilador se basa en la Directiva de coincidencia de plantilla DOM. Las directivas generalmente se pueden dividir en dos categorías:
Observar las directivas, como la expresión de Dobule-Curly {{Expression}}, registre el oyente usando el método $ Watch. Cada vez que cambia la expresión (valor), tales directivas deben ser notificadas para actualizar la vista.
La Directiva del oyente, como Ng-Click, registra un oyente en el DOM. Cuando el oyente del DOM dispara, la directiva ejecuta la expresión relevante y actualiza la vista utilizando el método $ Aplication.
Cuando se escucha un evento externo (como la acción del usuario, el temporizador o XHR), la expresión relevante debe aplicarse al alcance a través del método $ Aplication, para que todos los oyentes puedan actualizarse correctamente.
2. Directivas que crean ámbitos
En la mayoría de los casos, la directiva y el alcance están influyendo mutuamente, pero no se crea una nueva instancia de alcance. Sin embargo, algunas directivas (como Ng-Controller y Ng-Rpeat) crean un nuevo alcance, que agrega un alcance infantil al elemento DOM correspondiente. Vemos el alcance de cualquier elemento DOM usando Angular.Element (Adomelement) .Scope ().
3. Controladores y ámbitos
En los siguientes casos, el alcance y el controlador se influyen entre sí:
4. Alcance $ Consideraciones de rendimiento de reloj (alcance $ observaciones de rendimiento)
En Angular, es una operación común realizar una verificación sucia en el alcance para detectar cambios en los atributos. Para hacer esto, esto requiere que la función de verificación sucia sea eficiente. Tenga cuidado de que las funciones de verificación sucia no realicen operaciones de acceso DOM, porque el acceso DOM es órdenes de magnitud más lenta que acceder a las propiedades del objeto JavaScript.
Lo anterior es la información sobre el alcance de AngularJS. Continuaremos agregando información relevante en el futuro. ¡Gracias por su apoyo para este sitio!