Pregunta "Pensando en AngularJS" si tengo un fondo jQuery? [cerrado]


Supongamos que estoy familiarizado con el desarrollo de aplicaciones del lado del cliente en jQuery, pero ahora me gustaría empezar a usar AngularJS. ¿Puedes describir el cambio de paradigma que es necesario? Aquí hay algunas preguntas que pueden ayudarlo a enmarcar una respuesta:

  • ¿Cómo puedo diseñar y diseñar aplicaciones web del lado del cliente de manera diferente? ¿Cuál es la mayor diferencia?
  • ¿Qué debería dejar de hacer / usar? ¿Qué debería empezar a hacer / usar en su lugar?
  • ¿Hay consideraciones / restricciones del lado del servidor?

No estoy buscando una comparación detallada entre jQuery y AngularJS.


4525
2018-02-21 04:09


origen


Respuestas:


1. No diseñe su página, y luego cámbiela por DOM manipulaciones

En jQuery, diseñas una página y luego la haces dinámica. Esto se debe a que jQuery fue diseñado para el aumento y ha crecido increíblemente desde esa premisa simple.

Pero en AngularJS, debes comenzar desde cero con tu arquitectura en mente. En lugar de comenzar pensando "Tengo esta parte del DOM y quiero hacer que haga X", debe comenzar con lo que desea lograr, luego diseñe su aplicación y finalmente diseñe su vista.

2. No aumente jQuery con AngularJS

Del mismo modo, no empieces con la idea de que jQuery hace X, Y y Z, así que simplemente agregaré AngularJS además de eso para modelos y controladores. Esto es De Verdad Es tentador cuando recién comienzas, por lo que siempre recomiendo que los nuevos desarrolladores de AngularJS no usen jQuery en absoluto, al menos hasta que se acostumbren a hacer cosas como "Angular Way".

He visto muchos desarrolladores aquí y en la lista de correo crear estas elaboradas soluciones con jQuery plugins de 150 o 200 líneas de código que luego se pegan en AngularJS con una colección de callbacks y $applys que son confusas y complicadas; pero eventualmente lo hacen funcionar! El problema es que más casos en que el complemento jQuery podría reescribirse en AngularJS en una fracción del código, donde de repente todo se vuelve comprensible y directo.

La conclusión es la siguiente: cuando se soluciona, primero "piensa en AngularJS"; si no puede pensar en una solución, pregúntele a la comunidad; si después de todo eso no hay una solución fácil, entonces siéntase libre de alcanzar el jQuery. Pero no dejes que jQuery se convierta en una muleta o nunca dominarás AngularJS.

3. Siempre piense en términos de arquitectura

Primero sepa que aplicaciones de una sola página son aplicaciones. Ellos son no páginas web. Entonces, tenemos que pensar como un desarrollador del lado del servidor en adición a pensar como un desarrollador del lado del cliente. Tenemos que pensar en cómo dividir nuestra aplicación en componentes individuales, extensibles y comprobables.

Por lo que entonces cómo ¿Tú lo haces? ¿Cómo "piensas en AngularJS"? Aquí hay algunos principios generales, en contraste con jQuery.

La vista es el "registro oficial"

En jQuery, cambiamos la vista mediante programación. Podríamos tener un menú desplegable definido como ul al igual que:

<ul class="main-menu">
    <li class="active">
        <a href="#/home">Home</a>
    </li>
    <li>
        <a href="#/menu1">Menu 1</a>
        <ul>
            <li><a href="#/sm1">Submenu 1</a></li>
            <li><a href="#/sm2">Submenu 2</a></li>
            <li><a href="#/sm3">Submenu 3</a></li>
        </ul>
    </li>
    <li>
        <a href="#/home">Menu 2</a>
    </li>
</ul>

En jQuery, en nuestra lógica de aplicación, lo activaríamos con algo como:

$('.main-menu').dropdownMenu();

Cuando solo miramos la vista, no es inmediatamente obvio que haya alguna funcionalidad aquí. Para aplicaciones pequeñas, está bien. Pero para aplicaciones no triviales, las cosas se vuelven confusas y difíciles de mantener.

Sin embargo, en AngularJS, la vista es el registro oficial de la funcionalidad basada en visualización. Nuestra ul declaración se vería así en su lugar:

<ul class="main-menu" dropdown-menu>
    ...
</ul>

Estos dos hacen lo mismo, pero en la versión de AngularJS, cualquiera que mire la plantilla sabe lo que se supone que debe suceder. Cada vez que un nuevo miembro del equipo de desarrollo se une, puede ver esto y luego saber que hay una directiva llamada dropdownMenu operando en eso; ella no necesita intuir la respuesta correcta o revisar cualquier código. La vista nos dijo lo que se suponía que sucedería. Mucho más limpio.

Los desarrolladores nuevos en AngularJS a menudo hacen una pregunta como: ¿cómo puedo encontrar todos los enlaces de un tipo específico y agregar una directiva sobre ellos? El desarrollador siempre queda estupefacto cuando respondemos: no es así. Pero la razón por la que no haces eso es que esto es como half-jQuery, half-AngularJS, y no sirve. El problema aquí es que el desarrollador está tratando de "hacer jQuery" en el contexto de AngularJS. Eso nunca va a funcionar bien. La vista es el registro oficial. Fuera de una directiva (más sobre esto a continuación), nunca, nunca, Nunca cambia el DOM. Y se aplican directivas en la vista, entonces la intención es clara.

Recuerde: no diseñe y luego marque. Debe arquitecto y luego diseñar.

El enlace de datos

Esta es, con mucho, una de las características más sorprendentes de AngularJS y elimina la necesidad de realizar los tipos de manipulaciones DOM que mencioné en la sección anterior. ¡AngularJS actualizará automáticamente tu vista para que no tengas que hacerlo! En jQuery, respondemos a los eventos y luego actualizamos el contenido. Algo como:

$.ajax({
  url: '/myEndpoint.json',
  success: function ( data, status ) {
    $('ul#log').append('<li>Data Received!</li>');
  }
});

Para una vista que se ve así:

<ul class="messages" id="log">
</ul>

Además de mezclar preocupaciones, también tenemos los mismos problemas de intención significante que mencioné antes. Pero, lo que es más importante, tuvimos que hacer una referencia manual y actualizar un nodo DOM. Y si queremos eliminar una entrada de registro, tenemos que codificar contra el DOM para eso también. ¿Cómo probamos la lógica aparte del DOM? ¿Y qué pasa si queremos cambiar la presentación?

Esto un poco desordenado y un poco frágil. Pero en AngularJS, podemos hacer esto:

$http( '/myEndpoint.json' ).then( function ( response ) {
    $scope.log.push( { msg: 'Data Received!' } );
});

Y nuestra vista puede verse así:

<ul class="messages">
    <li ng-repeat="entry in log">{{ entry.msg }}</li>
</ul>

Pero para el caso, nuestra vista podría verse así:

<div class="messages">
    <div class="alert" ng-repeat="entry in log">
        {{ entry.msg }}
    </div>
</div>

Y ahora, en lugar de usar una lista desordenada, estamos usando cuadros de alerta de Bootstrap. ¡Y nunca tuvimos que cambiar el código del controlador! Pero más importante, no importa dónde o cómo el registro se actualiza, la vista también cambiará. Automáticamente. ¡Ordenado!

Aunque no lo mostré aquí, el enlace de datos es bidireccional. Entonces esos mensajes de registro también podrían ser editables en la vista simplemente haciendo esto: <input ng-model="entry.msg" />. Y hubo mucho regocijo.

Capa distintiva del modelo

En jQuery, el DOM es algo así como el modelo. Pero en AngularJS, tenemos una capa de modelo separada que podemos administrar de la manera que queramos, de forma completamente independiente de la vista. Esto ayuda a la vinculación de datos anterior, mantiene separación de interesese introduce una mayor capacidad de prueba. Otras respuestas mencionaron este punto, así que lo dejaré así.

Separación de intereses

Y todo lo anterior se relaciona con este tema general: mantenga sus preocupaciones separadas. Su vista actúa como el registro oficial de lo que se supone que sucederá (en su mayor parte); su modelo representa sus datos; tiene una capa de servicio para realizar tareas reutilizables; haces manipulación DOM y aumentas tu visión con directivas; y lo pegas todo junto con los controladores. Esto también se mencionó en otras respuestas, y lo único que agregaría se refiere a la capacidad de prueba, que analizo en otra sección a continuación.

Inyección de dependencia

Para ayudarnos con la separación de preocupaciones es inyección de dependencia (DI). Si vienes de un idioma del lado del servidor (desde Java a PHP) probablemente ya estés familiarizado con este concepto, pero si eres un tipo del lado del cliente que proviene de jQuery, este concepto puede parecer cualquier cosa, desde tonto a superfluo a hipster. Pero no lo es. :-)

Desde una perspectiva amplia, DI significa que puede declarar componentes muy libremente y luego desde cualquier otro componente, solo solicite una instancia y se le otorgará. No tiene que saber sobre el orden de carga, las ubicaciones de archivos ni nada de eso. El poder puede no ser visible inmediatamente, pero proporcionaré solo un ejemplo (común): prueba.

Digamos que en nuestra aplicación, necesitamos un servicio que implemente el almacenamiento del lado del servidor a través de un DESCANSO API y, dependiendo del estado de la aplicación, el almacenamiento local también. Al ejecutar pruebas en nuestros controladores, no queremos tener que comunicarnos con el servidor; estamos probando el controlador, después de todo. Podemos simplemente agregar un servicio simulado con el mismo nombre que nuestro componente original, y el inyector asegurará que nuestro controlador reciba el falso automáticamente - nuestro controlador no necesita y no necesita saber la diferencia.

Hablando de pruebas ...

4. Desarrollo basado en pruebas - siempre

Esto es realmente parte de la sección 3 sobre arquitectura, pero es tan importante que lo estoy poniendo como su propia sección de alto nivel.

De todos los muchos plugins de jQuery que ha visto, usado o escrito, ¿cuántos de ellos tenían un conjunto de pruebas de acompañamiento? No muchos porque jQuery no es muy receptivo a eso. Pero AngularJS es.

En jQuery, la única manera de probar es a menudo crear el componente de forma independiente con una página de muestra / demostración contra la cual nuestras pruebas pueden realizar la manipulación de DOM. Entonces, tenemos que desarrollar un componente por separado y entonces integrarlo en nuestra aplicación. ¡Qué inconveniente! La mayor parte del tiempo, cuando desarrollamos con jQuery, optamos por el desarrollo iterativo en lugar del basado en pruebas. ¿Y quién podría culparnos?

Pero debido a que tenemos una separación de preocupaciones, ¡podemos hacer un desarrollo impulsado por pruebas iterativamente en AngularJS! Por ejemplo, digamos que queremos una directiva súper simple para indicar en nuestro menú cuál es nuestra ruta actual. Podemos declarar lo que queremos en la vista de nuestra aplicación:

<a href="/hello" when-active>Hello</a>

De acuerdo, ahora podemos escribir una prueba para el inexistente when-active directiva:

it( 'should add "active" when the route changes', inject(function() {
    var elm = $compile( '<a href="/hello" when-active>Hello</a>' )( $scope );

    $location.path('/not-matching');
    expect( elm.hasClass('active') ).toBeFalsey();

    $location.path( '/hello' );
    expect( elm.hasClass('active') ).toBeTruthy();
}));

Y cuando ejecutamos nuestra prueba, podemos confirmar que falla. Solo ahora debemos crear nuestra directiva:

.directive( 'whenActive', function ( $location ) {
    return {
        scope: true,
        link: function ( scope, element, attrs ) {
            scope.$on( '$routeChangeSuccess', function () {
                if ( $location.path() == element.attr( 'href' ) ) {
                    element.addClass( 'active' );
                }
                else {
                    element.removeClass( 'active' );
                }
            });
        }
    };
});

Nuestra prueba ahora pasa y nuestro menú funciona según lo solicitado. Nuestro desarrollo es ambos iterativo y impulsado por la prueba. Wicked-cool.

5. Conceptualmente, las directivas son no empaquetado jQuery

A menudo escucharás "solo hacer manipulación DOM en una directiva". Esto es una necesidad Trátelo con la debida deferencia!

Pero vamos a sumergirnos un poco más profundo ...

Algunas directivas simplemente decoran lo que ya está en la vista (piense ngClass) y por lo tanto, a veces hacen la manipulación del DOM de inmediato y luego básicamente se hacen. Pero si una directiva es como un "widget" y tiene una plantilla, debería además respetar la separación de las preocupaciones. Es decir, la plantilla también debería permanecer en gran parte independiente de su implementación en las funciones de enlace y controlador.

AngularJS viene con un conjunto completo de herramientas para hacer esto muy fácil; con ngClass podemos actualizar dinámicamente la clase; ngModel permite el enlace de datos bidireccional; ngShow y ngHide mostrar u ocultar programáticamente un elemento; y muchos más, incluidos los que escribimos nosotros mismos. En otras palabras, podemos hacer todo tipo de genialidad sin Manipulación DOM Cuanta menos manipulación del DOM, más fáciles son las directivas para probar, cuanto más fáciles sean de estilo, más fácil será cambiar en el futuro y más reutilizables y distribuibles.

Veo muchos desarrolladores nuevos en AngularJS usando directivas como el lugar para lanzar un montón de jQuery. En otras palabras, piensan "dado que no puedo hacer la manipulación DOM en el controlador, tomaré ese código y lo pondré en una directiva". Si bien eso ciertamente es mucho mejor, a menudo sigue siendo incorrecto.

Piensa en el registrador que programamos en la sección 3. Incluso si lo ponemos en una directiva, todavía quiero hacerlo como "Angular Way". Eso todavía no toma ninguna manipulación DOM Hay muchas veces cuando la manipulación DOM es necesaria, pero es una mucho ¡Más raro de lo que piensas! Antes de hacer la manipulación DOM en cualquier sitio en su aplicación, pregúntese si realmente lo necesita. Puede haber una mejor manera.

Aquí hay un ejemplo rápido que muestra el patrón que veo con más frecuencia. Queremos un botón alternante. (Nota: este ejemplo es un poco artificial y un skosh verbose para representar casos más complicados que se resuelven exactamente de la misma manera).

.directive( 'myDirective', function () {
    return {
        template: '<a class="btn">Toggle me!</a>',
        link: function ( scope, element, attrs ) {
            var on = false;

            $(element).click( function () {
                on = !on;
                $(element).toggleClass('active', on);
            });
        }
    };
});

Hay algunas cosas mal con esto:

  1. Primero, jQuery nunca fue necesario. ¡No hay nada que hagamos aquí que necesite jQuery en absoluto!
  2. Segundo, incluso si ya tenemos jQuery en nuestra página, no hay razón para usarlo aquí; podemos simplemente usar angular.element y nuestro componente seguirá funcionando cuando se deje caer en un proyecto que no tiene jQuery.
  3. En tercer lugar, incluso asumiendo jQuery estaba requerido para que esta directiva funcione, jqLite (angular.element) será siempre ¡use jQuery si fue cargado! Entonces no necesitamos usar el $ - solo podemos usar angular.element.
  4. En cuarto lugar, estrechamente relacionado con el tercero, es que los elementos jqLite no necesitan ser envueltos en $ - el element eso se pasa al link la función sería ya sea un elemento jQuery!
  5. Y quinto, que hemos mencionado en secciones anteriores, ¿por qué estamos mezclando elementos de plantilla en nuestra lógica?

Esta directiva puede reescribirse (¡incluso en casos muy complicados!) De forma mucho más sencilla:

.directive( 'myDirective', function () {
    return {
        scope: true,
        template: '<a class="btn" ng-class="{active: on}" ng-click="toggle()">Toggle me!</a>',
        link: function ( scope, element, attrs ) {
            scope.on = false;

            scope.toggle = function () {
                scope.on = !scope.on;
            };
        }
    };
});

Una vez más, el material de la plantilla está en la plantilla, por lo que usted (o sus usuarios) pueden cambiarlo fácilmente por uno que se ajuste a cualquier estilo necesario, y el lógica nunca tuvo que ser tocado. Reutilización - ¡boom!

Y todavía hay todos esos otros beneficios, como las pruebas: ¡es fácil! Independientemente de lo que contenga la plantilla, la API interna de la directiva nunca se toca, por lo que la refactorización es sencilla. Puede cambiar la plantilla tanto como desee sin tocar la directiva. Y no importa lo que cambies, tus pruebas aún pasan.

w00t!

Entonces, si las directivas no son solo colecciones de funciones similares a jQuery, ¿qué son? Las directivas son en realidad extensiones de HTML. Si HTML no hace algo que usted necesita, usted escribe una directiva para que lo haga por usted, y luego lo usa como si fuera parte de HTML.

Dicho de otra manera, si AngularJS no hace algo de la caja, piense cómo lo lograría el equipo para encajar perfectamente con ngClick, ngClass, et al.

Resumen

Ni siquiera uses jQuery. Ni siquiera lo incluyas. Te retendrá. Y cuando llega a un problema que cree que ya sabe cómo resolver en jQuery, antes de llegar al $, intente pensar cómo hacerlo dentro de los límites AngularJS. Si no sabes, pregunta! 19 de cada 20 veces, la mejor manera de hacerlo no es jQuery y para tratar de resolverlo con jQuery resulta en más trabajo para usted.


7187
2018-02-21 21:26



Imperativo → declarativo

En jQuery, selectores se usan para encontrar DOM elementos y luego vincular / registrar controladores de eventos a ellos. Cuando se desencadena un evento, ese código (imperativo) se ejecuta para actualizar / cambiar el DOM.

En AngularJS, quieres pensar puntos de vista en lugar de elementos DOM. Las vistas son HTML (declarativo) que contienen AngularJS directivas. Las directivas configuran los controladores de eventos detrás de escena para nosotros y nos dan enlaces de datos dinámicos. Los selectores rara vez se utilizan, por lo que la necesidad de ID (y algunos tipos de clases) se ve muy disminuida. Las vistas están ligadas a modelos (a través de alcances). Las vistas son una proyección del modelo. Los eventos cambian los modelos (es decir, los datos, las propiedades del alcance) y las vistas que proyectan esos modelos se actualizan "automáticamente".

En AngularJS, piense en los modelos, en lugar de los elementos DOM seleccionados por jQuery que contienen sus datos. Piense en vistas como proyecciones de esos modelos, en lugar de registrar devoluciones de llamadas para manipular lo que ve el usuario.

Separación de intereses

jQuery emplea JavaScript discreto - el comportamiento (JavaScript) está separado de la estructura (HTML).

AngularJS usa controladores y directivas (cada una de las cuales puede tener su propio controlador y / o funciones de compilación y vinculación) para eliminar el comportamiento de la vista / estructura (HTML). Angular también tiene servicios y filtros para ayudar a separar / organizar su aplicación.

Ver también https://stackoverflow.com/a/14346528/215945

Diseño de la aplicación

Un enfoque para diseñar una aplicación AngularJS:

  1. Piensa en tus modelos. Cree servicios o sus propios objetos JavaScript para esos modelos.
  2. Piensa cómo quieres presentar tus modelos: tus puntos de vista. Cree plantillas HTML para cada vista, usando las directivas necesarias para obtener un enlace de datos dinámico.
  3. Adjunte un controlador a cada vista (usando ng-view y routing, o ng-controller). Haga que el controlador encuentre / obtenga solo los datos del modelo que la vista necesita para hacer su trabajo. Haga que los controladores sean lo más delgados posible.

Herencia Prototypal

Puede hacer mucho con jQuery sin saber cómo funciona la herencia prototípica de JavaScript. Al desarrollar aplicaciones AngularJS, evitará algunos errores comunes si comprende bien la herencia de JavaScript. Lectura recomendada: ¿Cuáles son los matices del alcance de la herencia prototípica / prototípica en AngularJS?


408
2018-02-21 04:09



AngularJS vs. jQuery

AngularJS y jQuery adoptan ideologías muy diferentes. Si vienes de jQuery, es posible que encuentres algunas de las diferencias sorprendentes. Angular puede hacerte enojar.

Esto es normal, deberías avanzar. Angular lo vale.

La gran diferencia (TLDR)

jQuery le proporciona un conjunto de herramientas para seleccionar bits arbitrarios del DOM y realizar cambios ad hoc en ellos. Puedes hacer prácticamente todo lo que quieras, pieza por pieza.

AngularJS en cambio le da una compilador.

Lo que esto significa es que AngularJS lee todo tu DOM de arriba a abajo y lo trata como código, literalmente como instrucciones para el compilador. A medida que atraviesa el DOM, busca un directivas (directivas del compilador) que le dicen al compilador AngularJS cómo comportarse y qué hacer. Las directivas son pequeños objetos llenos de JavaScript que pueden coincidir con atributos, etiquetas, clases o incluso comentarios.

Cuando el compilador angular determina que una parte del DOM coincide con una directiva particular, llama a la función directiva, pasándole el elemento DOM, cualquier atributo, el $ scope actual (que es un almacén de variables local) y algunos otros bits útiles. Estos atributos pueden contener expresiones que puedan ser interpretadas por la Directiva, y que le indiquen cómo renderizar, y cuándo debería volver a dibujarse.

Las directivas pueden, a su vez, incorporar componentes angulares adicionales, como controladores, servicios, etc. Lo que sale al pie del compilador es una aplicación web completamente formada, cableada y lista para funcionar.

Esto significa que Angular se maneja con una plantilla. Su plantilla maneja el JavaScript, no al revés. Esta es una inversión radical de los roles, y todo lo contrario del JavaScript discreto que hemos estado escribiendo durante los últimos 10 años más o menos. Esto puede tomar un tiempo para acostumbrarse.

Si esto parece ser demasiado prescriptivo y limitante, nada podría estar más lejos de la verdad. Como AngularJS trata su HTML como código, obtiene Granularidad de nivel de HTML en su aplicación web. Todo es posible, y la mayoría de las cosas son sorprendentemente fáciles una vez que realizas algunos saltos conceptuales.

Vayamos al grano.

Primero, Angular no reemplaza jQuery

Angular y jQuery hacen cosas diferentes. AngularJS le brinda un conjunto de herramientas para producir aplicaciones web. jQuery principalmente le brinda herramientas para modificar el DOM. Si jQuery está presente en su página, AngularJS lo usará automáticamente. Si no es así, AngularJS se envía con jQuery Lite, que es una versión reducida de jQuery pero perfectamente utilizable.

A Misko le gusta jQuery y no se opone a que lo uses. Sin embargo, a medida que avance, encontrará que puede hacer casi todo su trabajo utilizando una combinación de alcance, plantillas y directivas, y debe preferir este flujo de trabajo siempre que sea posible porque su código será más discreto, más configurable y más Angular.

Si usas jQuery, no deberías rociarlo por todos lados. El lugar correcto para la manipulación DOM en AngularJS está en una directiva. Más sobre esto más tarde.

JavaScript discreto con selectores vs. plantillas declarativas

jQuery generalmente se aplica discretamente. Su código JavaScript está vinculado en el encabezado (o en el pie de página), y este es el único lugar donde se menciona. Usamos selectores para seleccionar partes de la página y escribir complementos para modificar esas partes.

El JavaScript está bajo control El HTML tiene una existencia completamente independiente. Tu HTML sigue siendo semántico incluso sin JavaScript. Los atributos de OnClick son una mala práctica.

Una de las primeras cosas que notará sobre AngularJS es que los atributos personalizados están en todas partes. Su HTML estará lleno de atributos ng, que son esencialmente atributos onClick en esteroides. Estas son directivas (directivas de compilación), y son una de las principales formas en que la plantilla se engancha al modelo.

Cuando vea esto por primera vez, podría sentirse tentado de escribir AngularJS como el JavaScript intrusivo de la vieja escuela (como lo hice al principio). De hecho, AngularJS no juega según esas reglas. En AngularJS, tu HTML5 es una plantilla. AngularJS lo compila para producir su página web.

Esta es la primera gran diferencia. Para jQuery, su página web es un DOM que debe manipularse. Para AngularJS, tu código HTML es compilado. AngularJS lee en toda su página web y literalmente la compila en una nueva página web utilizando su compilador incorporado.

Su plantilla debe ser declarativa; su significado debe ser claro simplemente leyéndolo. Usamos atributos personalizados con nombres significativos. Creamos nuevos elementos HTML, nuevamente con nombres significativos. Un diseñador con conocimientos mínimos de HTML y sin habilidades de codificación puede leer su plantilla AngularJS y comprender lo que está haciendo. Él o ella pueden hacer modificaciones. Esta es la forma Angular.

La plantilla está en el asiento del conductor.

Una de las primeras preguntas que me hice al iniciar AngularJS y ejecutar los tutoriales es "¿Dónde está mi código?". No escribí ningún código JavaScript y, sin embargo, tengo todo este comportamiento. La respuesta es obvia Como AngularJS compila el DOM, AngularJS trata su código HTML como código. Para muchos casos simples, a menudo basta con escribir una plantilla y dejar que AngularJS la compile en una aplicación para usted.

Su plantilla dirige su aplicación. Se trata como un DSL. Usted escribe componentes AngularJS, y AngularJS se encargará de incluirlos y ponerlos a disposición en el momento adecuado según la estructura de su plantilla. Esto es muy diferente a un estándar MVC patrón, donde la plantilla es solo para la salida.

Es más similar a XSLT que Ruby on Rails por ejemplo.

Esta es una inversión radical de control que toma algún tiempo para acostumbrarse.

Deja de intentar manejar tu aplicación desde tu JavaScript. Deje que la plantilla controle la aplicación y deje que AngularJS se encargue de cablear los componentes entre sí. Esta también es la forma angular.

HTML semántico vs. modelos semánticos

Con jQuery, su página HTML debe contener contenido semántico significativo. Si JavaScript está desactivado (por un usuario o motor de búsqueda), su contenido permanece accesible.

Porque AngularJS trata su página HTML como una plantilla. No se supone que la plantilla sea semántica, ya que su contenido generalmente se almacena en su modelo, que en última instancia proviene de su API. AngularJS compila su DOM con el modelo para producir una página web semántica.

Su fuente HTML ya no es semántica, en cambio, su API y DOM compilados son semánticos.

En AngularJS, es decir, vive en el modelo, el HTML es solo una plantilla, solo para visualización.

En este punto es probable que tenga todo tipo de preguntas relativas a SEO y accesibilidad, y con razón. Hay problemas abiertos aquí. La mayoría de los lectores de pantalla ahora analizarán JavaScript. Los motores de búsqueda también pueden indexar AJAXed contenido. Sin embargo, querrás asegurarte de que estás utilizando URL de pushstate y de que tienes un mapa del sitio decente. Vea aquí para una discusión del problema: https://stackoverflow.com/a/23245379/687677

Separación de preocupaciones (SOC) vs. MVC

Separación de intereses (SOC) es un patrón que creció durante muchos años de desarrollo web por una variedad de razones que incluyen SEO, accesibilidad e incompatibilidad de navegadores. Se parece a esto:

  1. HTML - Significado semántico. El HTML debe estar solo.
  2. CSS - Estilo, sin CSS, la página aún es legible.
  3. JavaScript - Comportamiento, sin la secuencia de comandos, el contenido permanece.

Nuevamente, AngularJS no juega según sus reglas. En un accidente cerebrovascular, AngularJS elimina una década de sabiduría recibida y en su lugar implementa un patrón MVC en el que la plantilla ya no es semántica, ni siquiera un poco.

Se parece a esto:

  1. Modelo: sus modelos contienen sus datos semánticos. Los modelos son usualmente JSON objetos. Los modelos existen como atributos de un objeto llamado $ scope. También puede almacenar prácticas funciones de utilidad en $ scope a las que sus plantillas pueden acceder.
  2. Ver: sus puntos de vista están escritos en HTML. La vista generalmente no es semántica porque sus datos viven en el modelo.
  3. Controlador: su controlador es una función de JavaScript que engancha la vista al modelo. Su función es inicializar $ scope. Dependiendo de su aplicación, puede o no necesitar crear un controlador. Puede tener muchos controladores en una página.

MVC y SOC no están en extremos opuestos de la misma escala, están en ejes completamente diferentes. SOC no tiene sentido en un contexto AngularJS. Tienes que olvidarlo y seguir.

Si, como yo, sobreviviste a las guerras de los navegadores, es posible que esta idea te resulte ofensiva. Superarlo, valdrá la pena, lo prometo.

Complementos vs. Directivas

Los complementos se extienden jQuery. Las Directivas AngularJS amplían las capacidades de su navegador.

En jQuery definimos complementos al agregar funciones al jQuery.prototype. Luego enganchamos estos en el DOM seleccionando elementos y llamando al plugin sobre el resultado. La idea es ampliar las capacidades de jQuery.

Por ejemplo, si desea un carrusel en su página, puede definir una lista desordenada de figuras, quizás envuelta en un elemento de navegación. Luego puede escribir algo de jQuery para seleccionar la lista en la página y cambiarla como una galería con tiempos de espera para hacer la animación deslizante.

En AngularJS, definimos directivas. Una directiva es una función que devuelve un objeto JSON. Este objeto le dice a AngularJS qué elementos DOM buscar y qué cambios realizar en ellos. Las directivas están enganchadas a la plantilla utilizando los atributos o elementos que invente. La idea es ampliar las capacidades de HTML con nuevos atributos y elementos.

El modo AngularJS es ampliar las capacidades del HTML de aspecto nativo. Debe escribir HTML que se parece a HTML, extendido con atributos y elementos personalizados.

Si quieres un carrusel, solo usa un <carousel /> elemento, luego define una directiva para incorporar una plantilla y hacer que ese imbécil funcione.

Muchas directivas pequeñas frente a grandes complementos con conmutadores de configuración

La tendencia de jQuery es escribir grandes complementos como lightbox que luego configuramos al pasar numerosos valores y opciones.

Esto es un error en AngularJS.

Tome el ejemplo de un menú desplegable. Al escribir un complemento desplegable, es posible que tengas la tentación de codificar en los manejadores de clics, tal vez una función para agregar un cheurón que sea hacia arriba o hacia abajo, tal vez cambiar la clase del elemento desplegado, mostrar ocultar el menú, todo lo útil.

Hasta que quieras hacer un pequeño cambio.

Supongamos que tiene un menú que desea desplegar al pasar el mouse. Bueno, ahora tenemos un problema. Nuestro complemento se ha conectado en nuestro controlador de clics para nosotros, vamos a necesitar agregar una opción de configuración para que se comporte de manera diferente en este caso específico.

En AngularJS escribimos directivas más pequeñas. Nuestra directiva desplegable sería ridículamente pequeña. Puede mantener el estado doblado y proporcionar métodos para doblar (), desplegar () o alternar (). Estos métodos simplemente actualizarían $ scope.menu.visible, que es un booleano que contiene el estado.

Ahora en nuestra plantilla podemos conectar esto:

<a ng-click="toggle()">Menu</a>
<ul ng-show="menu.visible">
  ...
</ul>

¿Necesita actualizar en mouseover?

<a ng-mouseenter="unfold()" ng-mouseleave="fold()">Menu</a>
<ul ng-show="menu.visible">
  ...
</ul>

La plantilla dirige la aplicación para que obtengamos la granularidad del nivel de HTML. Si queremos hacer excepciones caso por caso, la plantilla lo hace fácil.

Cierre vs. $ alcance

Los complementos JQuery se crean en un cierre. La privacidad se mantiene dentro de ese cierre. Depende de usted mantener su cadena de alcance dentro de ese cierre. Solo tienes acceso al conjunto de nodos DOM pasados ​​al plugin por jQuery, más cualquier variable local definida en el cierre y cualquier variable global que hayas definido. Esto significa que los complementos son bastante independientes. Esto es algo bueno, pero puede ser restrictivo al crear una aplicación completa. Intentar pasar datos entre secciones de una página dinámica se convierte en una tarea ardua.

AngularJS tiene $ objetos de alcance. Estos son objetos especiales creados y mantenidos por AngularJS en el que almacena su modelo. Ciertas directivas generarán un nuevo $ scope, que por defecto hereda de su envoltura $ scope utilizando la herencia prototípica de JavaScript. El objeto $ scope es accesible en el controlador y la vista.

Esta es la parte inteligente. Debido a que la estructura de $ scope inheritance sigue aproximadamente la estructura del DOM, los elementos tienen acceso a su propio alcance, y cualquier ámbito que lo contenga sin problemas, hasta llegar al $ scope global (que no es lo mismo que el alcance global).

Esto hace que sea mucho más fácil pasar datos y almacenar datos en un nivel apropiado. Si se despliega un menú desplegable, solo el alcance $ desplegable necesita saber al respecto. Si el usuario actualiza sus preferencias, es posible que desee actualizar el $ scope global, y cualquier ámbito anidado que escuche las preferencias del usuario se alertará automáticamente.

Esto puede sonar complicado, de hecho, una vez que te relajas, es como volar. No es necesario crear el objeto $ scope, AngularJS crea una instancia para usted, de forma correcta y adecuada en función de la jerarquía de su plantilla. AngularJS luego lo pone a disposición de su componente utilizando la magia de la inyección de dependencia (más sobre esto más adelante).

Cambios manuales de DOM vs. Enlace de datos

En jQuery haces todos tus cambios DOM a mano. Usted construye nuevos elementos DOM programáticamente. Si tiene una matriz JSON y desea colocarla en el DOM, debe escribir una función para generar el HTML e insertarlo.

En AngularJS puede hacer esto también, pero se le recomienda hacer uso del enlace de datos. Cambia tu modelo, y como el DOM está vinculado a él a través de una plantilla, tu DOM se actualizará automáticamente, no se requiere intervención.

Debido a que el enlace de datos se realiza desde la plantilla, utilizando un atributo o la sintaxis de llaves, es muy fácil de hacer. Hay poca carga cognitiva asociada a ella, por lo que te encontrarás haciéndolo todo el tiempo.

<input ng-model="user.name" />

Vincula el elemento de entrada a $scope.user.name. La actualización de la entrada actualizará el valor en su alcance actual, y viceversa.

Igualmente:

<p>
  {{user.name}}
</p>

dará salida al nombre de usuario en un párrafo. Es un enlace en vivo, así que si $scope.user.name el valor se actualiza, la plantilla también se actualizará.

Ajax todo el tiempo

En jQuery hacer una llamada Ajax es bastante simple, pero aún así es algo sobre lo que podrías pensar dos veces. Existe la complejidad añadida para pensar y una buena porción de script para mantener.

En AngularJS, Ajax es su solución de acceso predeterminada y ocurre todo el tiempo, casi sin que se dé cuenta. Puede incluir plantillas con ng-include. Puede aplicar una plantilla con la directiva personalizada más simple. Puedes ajustar una llamada Ajax en un servicio y crearte un GitHub servicio, o un Flickr servicio, al que puede acceder con asombrosa facilidad.

Objetos de servicio vs funciones de ayuda

En jQuery, si queremos realizar una tarea pequeña no relacionada con el dominio, como extraer un feed de una API, podríamos escribir una pequeña función para hacer eso en nuestro cierre. Esa es una solución válida, pero ¿qué sucede si queremos acceder a ese feed a menudo? ¿Qué sucede si queremos reutilizar ese código en otra aplicación?

AngularJS nos da objetos de servicio.

Los servicios son objetos simples que contienen funciones y datos. Siempre son solteros, lo que significa que nunca puede haber más de uno. Digamos que queremos acceder a la API Stack Overflow, podríamos escribir un StackOverflowService que define los métodos para hacerlo.

Digamos que tenemos un carrito de compras. Podríamos definir un ShoppingCartService que mantenga nuestro carro y contenga métodos para agregar y eliminar artículos. Como el servicio es único, y lo comparten todos los demás componentes, cualquier objeto que lo necesite puede escribir en el carrito de compra y extraer datos del mismo. Siempre es el mismo carrito.

Los objetos de servicio son componentes autónomos de AngularJS que podemos usar y reutilizar como mejor nos parezca. Son objetos JSON simples que contienen funciones y datos. Siempre son únicos, por lo que si almacena datos en un servicio en un solo lugar, puede obtener esos datos en otro lugar simplemente solicitando el mismo servicio.

Inyección de dependencia (DI) vs. Instatiation - aka de-spaghettification

AngularJS administra sus dependencias por usted. Si desea un objeto, simplemente haga referencia a él y AngularJS lo obtendrá por usted.

Hasta que comiences a usar esto, es difícil explicar qué gran beneficio de tiempo es esto. No hay nada como AngularJS DI dentro de jQuery.

DI significa que en lugar de escribir su aplicación y conectarla, en su lugar define una biblioteca de componentes, cada uno identificado por una cadena.

Digamos que tengo un componente llamado 'FlickrService' que define los métodos para extraer feeds JSON de Flickr. Ahora, si quiero escribir un controlador que pueda acceder a Flickr, solo necesito referirme al 'FlickrService' por nombre cuando declaro el controlador. AngularJS se encargará de crear instancias del componente y ponerlo a disposición de mi controlador.

Por ejemplo, aquí defino un servicio:

myApp.service('FlickrService', function() {
  return {
    getFeed: function() { // do something here }
  }
});

Ahora cuando quiero usar ese servicio solo me refiero a este por su nombre así:

myApp.controller('myController', ['FlickrService', function(FlickrService) {
  FlickrService.getFeed()
}]);

AngularJS reconocerá que se necesita un objeto FlickrService para crear una instancia del controlador y nos proporcionará uno.

Esto hace que el cableado sea muy fácil y prácticamente elimina cualquier tendencia hacia la spagettificación. Tenemos una lista plana de componentes, y AngularJS nos los entrega uno por uno cuando los necesitamos.

Arquitectura de servicio modular

jQuery dice muy poco acerca de cómo debes organizar tu código. AngularJS tiene opiniones.

AngularJS le proporciona módulos en los que puede colocar su código. Si está escribiendo un guión que habla con Flickr, por ejemplo, puede querer crear un módulo de Flickr para ajustar todas sus funciones relacionadas con Flickr. Los módulos pueden incluir otros módulos (DI). Su aplicación principal suele ser un módulo, y esto debería incluir todos los demás módulos de los que dependerá su aplicación.

Obtiene la reutilización de código simple, si desea escribir otra aplicación basada en Flickr, puede simplemente incluir el módulo de Flickr y listo, tiene acceso a todas sus funciones relacionadas con Flickr en su nueva aplicación.

Los módulos contienen componentes AngularJS. Cuando incluimos un módulo, todos los componentes en ese módulo se vuelven disponibles para nosotros como una simple lista identificada por sus cadenas exclusivas.. Luego podemos inyectar esos componentes entre sí utilizando el mecanismo de inyección de dependencia de AngularJS.

Para resumir

AngularJS y jQuery no son enemigos. Es posible usar jQuery dentro de AngularJS muy bien. Si usa bien AngularJS (plantillas, enlace de datos, $ scope, directivas, etc.) encontrará que necesita un mucho menos jQuery de lo que de otra forma necesitarías.

Lo principal es darse cuenta de que su plantilla impulsa su aplicación. Deja de intentar escribir grandes complementos que hacen todo. En su lugar, escriba pequeñas instrucciones que hagan una cosa, luego escriba una plantilla simple para unirlas.

Piense menos acerca de JavaScript discreto, y en su lugar piense en términos de extensiones HTML.

Mi pequeño libro

Me entusiasmé tanto con AngularJS, escribí un breve libro sobre él, que le invito a leer en línea http://nicholasjohnson.com/angular-book/. Espero que sea útil.


184
2018-05-12 10:22



¿Puedes describir el cambio de paradigma que es necesario?

Imperativo vs declarativo

Con jQuery usted le dice al DOM lo que debe suceder, paso a paso. Con AngularJS usted describe los resultados que desea, pero no cómo hacerlo. Más sobre esto aquí. Además, mira la respuesta de Mark Rajcok.

¿Cómo puedo diseñar y diseñar aplicaciones web del lado del cliente de manera diferente?

AngularJS es un marco completo del lado del cliente que usa MVC patrón (echa un vistazo a su representación grafica) Se enfoca mucho en la separación de preocupaciones.

¿Cuál es la mayor diferencia? ¿Qué debería dejar de hacer / usar? ¿Qué debería empezar a hacer / usar en su lugar?

jQueryes una biblioteca

AngularJS es un marco del lado del cliente hermoso, altamente comprobable, que combina toneladas de cosas interesantes como MVC, inyección de dependencia, enlace de datos y mucho más.

Se enfoca en separación de intereses y prueba (examen de la unidad y pruebas de extremo a extremo), lo que facilita el desarrollo basado en pruebas.

La mejor manera de comenzar es pasando por su increíble tutorial. Puede seguir los pasos en un par de horas; sin embargo, en caso de que quiera dominar los conceptos detrás de escena, incluyen una gran cantidad de referencias para lecturas adicionales.

¿Hay consideraciones / restricciones del lado del servidor?

Puede usarlo en aplicaciones existentes donde ya está usando jQuery puro. Sin embargo, si desea aprovechar al máximo las características de AngularJS, puede considerar codificar el lado del servidor utilizando un Sosegado enfoque.

Hacerlo le permitirá aprovechar su fábrica de recursos, lo que crea una abstracción de su lado del servidor RESTful API y hace que las llamadas del lado del servidor (obtener, guardar, eliminar, etc.) sean increíblemente fáciles.


152
2018-02-21 04:29



Para describir el "cambio de paradigma", creo que una respuesta corta puede ser suficiente.

AngularJS cambia la forma en que encontrar elementos

En jQuery, normalmente utilizas selectores para encontrar elementos y luego conectarlos:
$('#id .class').click(doStuff);

En AngularJS, tu usas directivas para marcar los elementos directamente, para conectarlos:
<a ng-click="doStuff()">

AngularJS no necesita (ni desea) que encuentre elementos utilizando selectores: la diferencia principal entre AngularJS jqLite versus en toda regla jQuery es eso jqLite no admite selectores.

Entonces, cuando la gente dice "no incluyas jQuery en absoluto", es principalmente porque no quieren que uses selectores; ellos quieren que aprendas a usar directivas en su lugar. Directo, no seleccionado!


84
2018-02-21 07:57



jQuery

jQuery hace comandos de JavaScript ridículamente largos como getElementByHerpDerp más corto y navegador cruzado.

AngularJS

AngularJS le permite crear sus propias etiquetas / atributos HTML que hacen cosas que funcionan bien con aplicaciones web dinámicas (ya que HTML se diseñó para páginas estáticas).

Editar:

Al decir "Tengo un fondo jQuery, ¿cómo creo en AngularJS?" es como decir "Tengo un fondo HTML, ¿cómo puedo pensar en JavaScript?" El hecho de que haga la pregunta muestra que probablemente no comprenda los propósitos fundamentales de estos dos recursos. Es por eso que elegí responder la pregunta simplemente señalando la diferencia fundamental en lugar de pasar por la lista diciendo "AngularJS hace uso de directivas mientras que jQuery usa selectores de CSS para hacer un objeto jQuery que hace esto y aquello, etc." . Esta pregunta no requiere una respuesta larga.

jQuery es una forma de facilitar la programación de JavaScript en el navegador. Comandos más cortos, entre navegadores, etc.

AngularJS extiende HTML, por lo que no tiene que poner <div> por todo el lugar solo para hacer una solicitud. Hace que HTML funcione realmente para aplicaciones en lugar de para lo que fue diseñado, que es páginas web educativas y estáticas. Lo logra de forma indirecta utilizando JavaScript, pero fundamentalmente es una extensión de HTML, no de JavaScript.


69
2018-02-04 05:07



jQuery: piensas mucho sobre 'QUERY el DOM'para elementos DOM y hacer algo.

AngularJS: EL modelo es la verdad, y siempre piensas desde ese ÁNGULO.

Por ejemplo, cuando obtiene datos del servidor THE que tiene la intención de mostrar en algún formato en el DOM, en jQuery, necesita '1. ENCUENTRA 'en qué lugar del DOM deseas colocar esta información, el' 2. ACTUALÍZALO / APÉNDALO allí creando un nuevo nodo o simplemente estableciendo su innerHTML. Luego, cuando desee actualizar esta vista, entonces '3. ENCUENTRE 'la ubicación y' 4. ACTUALIZAR'. Este ciclo de búsqueda y actualización de todo lo realizado en el mismo contexto de obtención y formateo de datos del servidor no se encuentra en AngularJS.

Con AngularJS tiene su modelo (objetos JavaScript a los que ya está acostumbrado) y el valor del modelo le informa sobre el modelo (obviamente) y sobre la vista, y una operación en el modelo se propaga automáticamente a la vista, por lo que no tengo que pensar en eso Te encontrarás en AngularJS ya no encontrarás cosas en el DOM.

Para decirlo de otra manera, en jQuery, debe pensar en los selectores de CSS, es decir, ¿dónde está el div o td que tiene una clase o atributo, etc., para que pueda obtener su HTML o color o valor, pero en AngularJS, se encontrará pensando así: con qué modelo estoy tratando, estableceré el valor del modelo en verdadero. No se está molestando si la vista que refleja este valor es una casilla marcada o reside en un td elemento (detalles que a menudo necesitaría pensar en jQuery).

Y con la manipulación DOM en AngularJS, se encuentra agregando directivas y filtros, que puede considerar extensiones válidas de HTML.

Una cosa más que experimentará en AngularJS: en jQuery llama mucho a las funciones de jQuery, en AngularJS, AngularJS llamará a sus funciones, por lo que AngularJS 'le dirá cómo hacer las cosas', pero los beneficios valen la pena, así que aprender AngularJS generalmente significa aprender lo que AngularJS quiere o la forma en que AngularJS requiere que presente sus funciones y lo llamará en consecuencia. Esta es una de las cosas que hace AngularJS un marco en lugar de una biblioteca.


61
2017-11-02 16:53