Para mí, que es un novato puro en la parte delantera, JavaScript sigue siendo un poco claro al respecto. Si quieres comenzar directamente con JS Angular, realmente hay mucha resistencia. Pero creo que mientras trabajes duro, incluso el diseño antihumano no será un gran problema.
Bien, no digas muchas tonterías. Para averiguar qué es Angular JS, comencé con el alcance. Entonces, ¿qué es el alcance? Tomar prestado un pasaje del documento oficial:
La copia del código es la siguiente:
"El alcance es un objeto que se refiere al modelo de aplicación. Es un contexto de ejecución para expresiones. Los ámbitos se organizan en la estructura jerárquica que imita la estructura DOM de la aplicación. Los ámbitos pueden ver expresiones y propagar eventos".
Después de leerlo, lo comparé con otros lenguajes de programación y sentí que el alcance es como el alcance del modelo de datos, proporcionando contexto para la ejecución de expresiones. Entendamos de esta manera por ahora.
Características del alcance
A continuación, veamos qué características tienen el alcance.
El alcance proporciona el método $ reloj para monitorear los cambios en el modelo.
El alcance proporciona un método de aplicar $ para propagar cambios en el modelo.
El alcance se puede heredar y aísla diferentes componentes de la aplicación y permisos de acceso a atributos.
El alcance proporciona contexto para el cálculo de expresiones.
Para estas cuatro características, debido a que he aprendido ActionScript, C ++ y Java antes, no es difícil entender los puntos primeros, terceros y cuarto, pero el segundo punto se siente un poco confuso. Basado en el principio de romper la cacerola y preguntar el final, todavía encontré algunas cosas a través de Google. Para los veteranos experimentados, ¡por favor da palmaditas en los ladrillos!
Origen de JavaScript
En primer lugar, a primera vista, Scope.apply () parece ser un método ordinario para hacer una actualización de enlaces. Pero piense un poco más, ¿por qué lo necesitamos? ¿Cuándo lo usas suele usar? Para comprender estos dos problemas, tenemos que comenzar con JavaScript. En el código JavaScript, se ejecutan en un cierto orden. Cuando se ejecuta el giro de un fragmento de código, el navegador solo ejecutará el fragmento actual y no hará nada más. Por lo tanto, a veces algunas páginas web que no están bien hechas se atascarán al hacer clic en algo. ¡JavaScript trabaja una de las razones por las cuales este fenómeno es causado! Aquí tenemos un código para experimentarlo:
La copia del código es la siguiente:
bot button = document.getElementById ('clickMe');
función buttonclicked () {
alerta ('se hizo clic en el botón');
}
botón.AdDeventListener ('Haga clic', Button -Clicked);
función timerComplete () {
alerta ('Temporizador completo');
}
setTimeOut (TimerComplete, 5000);
Al cargar el código JavaScript, primero busque un botón con una ID llamada "ClickMe", luego agregue un oyente y luego configure el tiempo de espera. Espere 5 segundos y aparecerá un cuadro de diálogo. Si actualiza la página y haga clic en el botón ClickMe inmediatamente, aparecerá un cuadro de diálogo. Si no hace clic en Aceptar, la función TimerComplete nunca tendrá la oportunidad de ejecutar.
Cómo actualizar los enlaces
De acuerdo, después de hablar de algo que parece irrelevante, volvamos al tema. ¿Cómo sabe Angular JS cuando los datos cambian y las páginas deben actualizarse? El código necesita saber cuándo se han modificado los datos, pero ahora no hay forma de informar directamente los datos sobre un objeto que ha cambiado (aunque Ecmascript 5 está tratando de resolver este problema, todavía está en la etapa experimental). Actualmente, hay dos soluciones para las estrategias más convencionales. Una es usar objetos especiales para que todos los datos solo se puedan establecer llamando al método de objeto, en lugar de especificarlo directamente a través de la propiedad. De esta manera, se pueden grabar todas las modificaciones y sabrá cuándo debe actualizarse la página. La desventaja de hacer esto es que debemos heredar un objeto especial. Para la asignación, solo se puede hacer por object.set ('clave', 'valor') en lugar de object.key = value. En los marcos, esto es lo que hacen Emberjs y Knockoutjs (aunque no lo he tocado antes). Otro método es el método adoptado por Angular JS, que verifica si hay algún cambio de datos después de que se ejecute cada secuencia de ejecución del código JavaScript. Esto no parece ser eficiente e incluso afecta seriamente el rendimiento. Sin embargo, Angular JS usa algunos medios inteligentes para resolver este problema (aún no se ha estudiado y aún no está claro). La ventaja de hacer esto es que podemos usar cualquier objeto a voluntad, no hay límite en el método de asignación, y también podemos conocer los cambios de datos.
Para esta solución adoptada por Angular JS, nos importa cuándo cambia los datos, y ahí es donde scope.apply () es útil. Comprobando si los datos unidos han cambiado, en realidad se realiza por Scope.digest (), pero casi nunca hemos llamado este método directamente, sino que llamamos el método Scope.apply () porque en el método Scope.apply (), llamará al método Scope.digest (). El método Scope.apply () toma una función o una expresión, luego la ejecuta y finalmente llama al método Scope.digest () para actualizar los enlaces o observadores.
Cuándo usar $ Aplicar ()
La misma pregunta es, entonces, ¿cuándo necesitamos llamar al método Aplicar ()? Hay muy pocos casos. De hecho, casi todo nuestro código está envuelto en Scope.apply (), como Ng-Click, Inicialización del controlador, funciones de devolución de llamada HTTP, etc. En estos casos, no necesitamos llamarnos a nosotros mismos, y de hecho no podemos llamarnos a nosotros mismos, de lo contrario llamando al método Aplicar () en el método Aplicar () lanzará un error. Si necesitamos ejecutar el código en una nueva secuencia de ejecución, realmente necesitamos usarlo, y si y solo si la nueva secuencia de ejecución no es creada por el método de la biblioteca JS Angular, necesitamos envolver el código en Scope.apply (). Aquí hay un ejemplo para explicar:
La copia del código es la siguiente:
<div ng: app ng-confontroller = "ctrl"> {{mensaje}} </div>
La copia del código es la siguiente:
functionCtrl ($ alcope) {
$ scope.message = "Waiting 2000ms para actualizar";
setTimeOut (function () {
$ scope.message = "Tiempo de espera llamado!";
// Angularjs desconoce la actualización a $ alcance
}, 2000);
}
Después de ejecutar el código anterior, la página se mostrará: espera 2000 ms para actualizar. Obviamente, la actualización de los datos no fue detectada por Angular JS.
A continuación, modificamos ligeramente el código JavaScript y lo envolvemos con Scope.apply ().
La copia del código es la siguiente:
functionCtrl ($ alcope) {
$ scope.message = "Waiting 2000ms para actualizar";
setTimeOut (function () {
$ alcance. $ Aplicar (function () {
$ scope.message = "Tiempo de espera llamado!";
});
}, 2000);
}
La diferencia esta vez es que la página se mostrará por primera vez: espera 2000 ms para actualizar. Después de esperar 2 segundos, el contenido se cambiará a: ¡Tiempo de espera llamado! . Obviamente, la actualización de los datos fue detectada por Angular JS.
Nota: No debemos hacer esto, pero usar el método de tiempo de espera proporcionado por Angular JS, para que se envuelva automáticamente con el método Aplicar.
La ciencia es una espada de doble filo
Finalmente, echemos un vistazo al alcance.apply () y los métodos de alcance.apply (función) nuevamente! Aunque Angular JS hizo mucho por nosotros, también perdimos algunas oportunidades. Puede ver desde el siguiente pseudocódigo:
La copia del código es la siguiente:
función $ aplicar (expr) {
intentar {
devolver $ eval (expr);
} catch (e) {
$ ExceptionHandler (e);
} finalmente {
$ root. $ digest ();
}
}
Atrapará todas las excepciones y no las volverá a lanzar, y eventualmente llamará al método $ digest ().
Resumimos
El método $ Apply () puede ejecutar expresiones JS angulares fuera del marco angular, como: eventos DOM, setTimeOut, XHR u otras bibliotecas de terceros. Esto es solo el comienzo, el agua sigue siendo profunda, ¡bienvenido a profundidad de buceo juntos!