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


4514

Supongamos que estoy familiarizado con el desarrollo de aplicaciones del lado del cliente en jQuery , pero ahora me gustaría comenzar a usar AngularJS . ¿Puedes describir el cambio de paradigma que es necesario? Aquí hay algunas preguntas que pueden ayudarlo a formular 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é debo dejar de hacer / usar? ¿Qué debo comenzar a hacer / usar en su lugar?
  • ¿Hay alguna consideración / restricción del lado del servidor?

No estoy buscando una comparación detallada entre jQueryy AngularJS.


Para aquellos familiarizados con "ASP.NET MVC" o "RoR", solo piense en Angular como "MVC del lado del cliente" y eso es todo.
Serge Shultz

Respuestas:


7178

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

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

Pero en AngularJS, debe comenzar desde cero con su arquitectura en mente. En lugar de comenzar por pensar "Tengo esta parte del DOM y quiero que sea X", debe comenzar con lo que desea lograr, luego diseñar su aplicación y finalmente diseñar su vista.

2. No aumente jQuery con AngularJS

Del mismo modo, no comience con la idea de que jQuery hace X, Y y Z, por lo que solo agregaré AngularJS además de eso para modelos y controladores. Esto es realmente tentador cuando recién estás comenzando, por eso siempre recomiendo que los nuevos desarrolladores de AngularJS no usen jQuery, al menos hasta que se acostumbren a hacer las cosas de la "manera angular".

He visto a muchos desarrolladores aquí y en la lista de correo crear estas elaboradas soluciones con complementos jQuery de 150 o 200 líneas de código que luego pegan en AngularJS con una colección de devoluciones de llamada y mensajes $applyconfusos y complicados; ¡pero finalmente lo hacen funcionar! El problema es que, en la mayoría de los casos, 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 esta: al resolver, primero "piense en AngularJS"; si no puede pensar en una solución, pregúntele a la comunidad; Si después de todo esto no hay una solución fácil, entonces no dude en alcanzar el jQuery. Pero no dejes que jQuery se convierta en una muleta o nunca dominarás AngularJS.

3. Siempre piensa en términos de arquitectura

Primero sepa que las aplicaciones de una sola página son aplicaciones . Son no páginas web. Por lo tanto, debemos pensar como un desarrollador del lado del servidor además de pensar como un desarrollador del lado del cliente. Tenemos que pensar en cómo dividir nuestra aplicación en componentes individuales, extensibles y comprobables.

Entonces, ¿cómo haces eso? ¿Cómo "piensas en AngularJS"? Aquí hay algunos principios generales, en contraste con jQuery.

La vista es el "registro oficial"

En jQuery, cambiamos programáticamente la vista. Podríamos tener un menú desplegable definido ulcomo así:

<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 rápidamente.

Sin embargo, en AngularJS, la vista es el registro oficial de la funcionalidad basada en la vista. Nuestra uldeclaració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 AngularJS cualquiera que mire la plantilla sabe lo que se supone que debe suceder. Cada vez que se incorpora un nuevo miembro del equipo de desarrollo, puede mirar esto y luego saber que hay una directiva llamada dropdownMenuoperar en él; ella no necesita intuir la respuesta correcta o examinar 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 encuentro todos los enlaces de un tipo específico y agrego una directiva sobre ellos? El desarrollador siempre queda estupefacto cuando respondemos: usted no. 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 más adelante), nunca, nunca, nunca se cambie el DOM. Y las directivas se aplican en la vista , por lo que la intención es clara.

Recuerde: no diseñe y luego marque. Debes diseñar, y luego diseñar.

El enlace de datos

Esta es, con mucho, una de las características más impresionantes de AngularJS y elimina la necesidad de realizar los tipos de manipulaciones DOM que mencioné en la sección anterior. AngularJS actualizará automáticamente su vista para que no tenga que hacerlo. En jQuery, respondemos a 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 de significado que mencioné antes. Pero lo que es más importante, tuvimos que hacer referencia y actualizar manualmente un nodo DOM. Y si queremos eliminar una entrada de registro, también tenemos que codificar contra el DOM. ¿Cómo probamos la lógica aparte del DOM? ¿Y si queremos cambiar la presentación?

Esto es 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 visión 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 lo más importante, no importa dónde o cómo se actualice el registro, la vista también cambiará. Automáticamente. ¡Ordenado!

Aunque no lo mostré aquí, el enlace de datos es bidireccional. Así que los mensajes de registro también podría ser modificable en la vista sólo por hacer esto: <input ng-model="entry.msg" />. Y hubo mucho regocijo.

Capa de modelo distinta

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

Separación de intereses

Y todo lo anterior está relacionado con este tema general: mantenga sus preocupaciones separadas. Su punto de vista actúa como el registro oficial de lo que se supone que debe 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 punto de vista 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 discuto en otra sección a continuación.

Inyección de dependencia

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

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

Digamos que en nuestra aplicación, requerimos un servicio que implemente el almacenamiento del lado del servidor a través de una API REST y, dependiendo del estado de la aplicación, también el almacenamiento local. Cuando ejecutamos pruebas en nuestros controladores, no queremos tener que comunicarnos con el servidor ; después de todo, estamos probando el controlador . Simplemente podemos agregar un servicio simulado con el mismo nombre que nuestro componente original, y el inyector se asegurará de que nuestro controlador obtenga el falso automáticamente; nuestro controlador no sabe 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 pongo como su propia sección de nivel superior.

De todos los muchos complementos de jQuery que has visto, usado o escrito, ¿cuántos de ellos tenían un conjunto de pruebas? No muchos porque jQuery no es muy susceptible a eso. Pero AngularJS es.

En jQuery, la única forma 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 DOM. Entonces, tenemos que desarrollar un componente por separado y luego integrarlo en nuestra aplicación. ¡Qué inconveniente! Gran parte del tiempo, al desarrollar con jQuery, optamos por un desarrollo iterativo en lugar de un desarrollo basado en pruebas. ¿Y quién podría culparnos?

¡Pero debido a que tenemos una separación de preocupaciones, podemos hacer un desarrollo basado en pruebas de forma iterativa en AngularJS! Por ejemplo, supongamos que queremos que una directiva súper simple indique 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>

Bien, ahora podemos escribir una prueba para la when-activedirectiva inexistente :

it( 'should add "active" when the route changes', inject(function() {
    var elm = $compile( '<a href="https://stackoverflow.com/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 deberíamos 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 tanto iterativo como probado. Genial.

5. Conceptualmente, las directivas no están empaquetadas jQuery

A menudo escuchará "solo manipula DOM en una directiva". Esto es una necesidad ¡Trátelo con la debida deferencia!

Pero profundicemos un poco más ...

Algunas directivas simplemente decoran lo que ya está en la vista (pensar ngClass) y, por lo tanto, a veces realizan la manipulación DOM de inmediato y luego básicamente se hacen. Pero si una directiva es como un "Widget" y tiene una plantilla, debe también respetar la separación de preocupaciones. Es decir, la plantilla también debe permanecer en gran medida 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 ngClasspodemos actualizar dinámicamente la clase; ngModelpermite enlace de datos bidireccional; ngShowy ngHidemuestra u oculta programáticamente un elemento; y muchos más, incluidos los que escribimos nosotros mismos. En otras palabras, podemos hacer todo tipo de genialidad sin la manipulación DOM. Cuanta menos manipulación DOM, más fáciles de probar las directivas, más fáciles de diseñar, más fáciles de cambiar en el futuro y más reutilizables y distribuibles.

Veo muchos desarrolladores nuevos en AngularJS que usan directivas como el lugar para lanzar un montón de jQuery. En otras palabras, piensan "como 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 todavía está mal .

Piense en el registrador que programamos en la sección 3. Incluso si lo ponemos en una directiva, todavía queremos hacerlo "Angular Way". ¡ Todavía no requiere ninguna manipulación DOM! Hay muchas ocasiones en que es necesaria la manipulación DOM, ¡pero es mucho más raro de lo que piensas! Antes de realizar la manipulación DOM en cualquier parte de 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 que se pueda alternar. (Nota: este ejemplo es un poco ingenioso y un skosh detallado 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 hicimos nada aquí que necesitara jQuery!
  2. Segundo, incluso si ya tenemos jQuery en nuestra página, no hay razón para usarlo aquí; simplemente podemos usar angular.elementy nuestro componente seguirá funcionando cuando se deje caer en un proyecto que no tenga jQuery.
  3. En tercer lugar, incluso suponiendo que se requiera jQuery para que esta directiva funcione, jqLite ( angular.element) siempre usará jQuery si se cargó. Por lo tanto, no necesitamos usar el $- solo podemos usarlo angular.element.
  4. El cuarto, estrechamente relacionado con el tercero, es que los elementos jqLite no necesitan estar envueltos $: ¡el elementque se pasa a la linkfunción ya sería 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 se puede reescribir (¡incluso en casos muy complicados!) Mucho más simplemente así:

.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 contenido de la plantilla está en la plantilla, por lo que usted (o sus usuarios) pueden cambiarlo fácilmente por uno que cumpla con cualquier estilo necesario, y la lógica nunca tuvo que ser tocada. Reutilización - ¡boom!

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

w00t!

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

Dicho de otra manera, si AngularJS no hace algo fuera de la caja, piense cómo el equipo lograría que se ajuste perfectamente con ngClick, ngClasset al.

Resumen

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


204204
Creo que incorporar trabajar con JQuery dentro de una aplicación angular es un caso de uso importante debido a todos los complementos JQuery existentes que se han escrito. No estoy reescribiendo FancyBox en jQuery para mantener una aplicación Angular pura.
taudep

119
@taudep No creo que estemos en desacuerdo tanto como piensas. La mayoría de los complementos de jQuery se pueden reescribir en AngularJS a bajo costo, y en esos casos deberíamos hacerlo. Para algo complejo para el que no hay un equivalente, entonces ve por él. Para citar de la Sección 2: 'La conclusión es esta: al resolver, primero "piense 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, no dude en buscar jQuery . Pero no dejes que jQuery se convierta en una muleta o nunca dominarás AngularJS ''. [énfasis agregado]
Josh David Miller

67
Un chino traduce a esta gran respuesta, espero que sea útil. hanzheng.github.io/tech/angularjs/2013/10/28/…
Han Zheng

18
@Benno Lo que quiere decir con "sin manipulación DOM" es que su código en la directiva no realiza directamente manipulaciones DOM. Ese código no sabe nada sobre el DOM, solo está modificando las variables js en su modelo. Sí, el resultado final es que el DOM se modifica, pero eso se debe a que fuera del código que escribimos, hay enlaces que reaccionan al cambio de nuestras variables, pero dentro de la directiva no sabemos nada al respecto, haciendo una separación clara entre la manipulación del DOM y lógica de negocios. En su ejemplo de jQuery, está cambiando directamente el DOM al decir "agregar este texto a este elemento"
wired_in

11
@trusktr Si un desarrollo alguna vez establece el valor de un elemento de entrada usando jQuery en una aplicación AngularJS, está cometiendo un grave error. El único tipo de excepción que puedo pensar es un complemento jQuery existente que es demasiado difícil de portar y que cambia una entrada automáticamente, en cuyo caso enganchar una devolución de llamada o configurar un reloj es absolutamente esencial de todos modos para que los cambios estén en línea con la aplicación.
Josh David Miller

407

Imperativo → declarativo

En jQuery, los selectores se utilizan para buscar elementos DOM y luego vincularlos / registrar controladores de eventos. Cuando se activa un evento, ese código (imperativo) se ejecuta para actualizar / cambiar el DOM.

En AngularJS, desea pensar en vistas en lugar de elementos DOM. Las vistas son HTML (declarativas) que contienen directivas AngularJS . Las directivas configuran los controladores de eventos detrás de escena para nosotros y nos proporcionan un enlace de datos dinámico. Los selectores rara vez se usan, por lo que la necesidad de ID (y algunos tipos de clases) se ve muy disminuida. Las vistas están vinculadas a modelos (a través de ámbitos). Las vistas son una proyección del modelo. Los eventos cambian los modelos (es decir, datos, propiedades del alcance) y las vistas que proyectan esos modelos se actualizan "automáticamente".

En AngularJS, piense en modelos, en lugar de elementos DOM seleccionados por jQuery que contienen sus datos. Piense en las vistas como proyecciones de esos modelos, en lugar de registrar devoluciones de llamada 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 utiliza controladores y directivas (cada una de las cuales puede tener su propio controlador y / o compilar y vincular funciones) 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. Piense en cómo quiere presentar sus modelos: sus puntos de vista. Cree plantillas HTML para cada vista, utilizando las directivas necesarias para obtener un enlace de datos dinámico.
  3. Adjunte un controlador a cada vista (usando ng-view y enrutamiento, o ng-controller). Haga que el controlador encuentre / obtenga solo los datos del modelo que la vista necesita para hacer su trabajo. Haga los controladores lo más delgados posible.

Herencia prototípica

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


1
¿Puedes por favor? explicar cómo un elemento dom es diferente de una vista?
Rajkamal Subramanian

22
@rajkamal, un elemento DOM es (obviamente) un elemento único, y en jQuery eso es a menudo lo que seleccionamos / seleccionamos / manipulamos. Una vista angular es una colección / plantilla de elementos DOM relacionados: vista de menú, vista de encabezado, vista de pie de página, vista de barra lateral derecha, vista de perfil, quizás múltiples vistas de contenido principal (intercambiables a través de ng-view). Básicamente, desea dividir sus páginas en diferentes vistas. Cada vista tiene su propio controlador asociado. Cada vista proyecta parte de su (s) modelo (s).
Mark Rajcok

3
jQuery NO es imprescindible. ony whenson funciones de orden superior, que operan en miembros de un objeto de colección jQuery.
Jack Viers

18
Entonces, ¿para qué tipo de código se ejecuta en la devolución de llamada on? Imperativo.
cwharris

55
Este imperativo versus declarativo es realmente solo una cuestión de abstracciones. Al final, todo el código declarativo (qué hacer) se implementa imperativamente (cómo hacerlo) ya sea por el desarrollador en una subrutina en un nivel de abstracción inferior, por el marco o un compilador / intérprete. Decir que "jQuery es imperativo" en general es una afirmación bastante extraña, especialmente considerando que en realidad proporciona una API mucho más declarativa con respecto a la manipulación DOM "manual".
Alex

184

AngularJS vs.JQuery

AngularJS y jQuery adoptan ideologías muy diferentes. Si viene de jQuery, puede encontrar algunas de las diferencias sorprendentes. Angular puede hacerte enojar.

Esto es normal, debes seguir adelante. Angular lo vale.

La gran diferencia (TLDR)

jQuery le ofrece un kit 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 te da un compilador .

Lo que esto significa es que AngularJS lee todo su DOM de arriba a abajo y lo trata como código, literalmente como instrucciones para el compilador. A medida que atraviesa el DOM, busca directivas específicas ( 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 de directiva, pasándole el elemento DOM, cualquier atributo, el $ alcance actual (que es un almacén de variables local) y algunos otros bits útiles. Estos atributos pueden contener expresiones que pueden ser interpretadas por la Directiva, y que le dicen cómo representar y cuándo debe volver a dibujarse.

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

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

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

Vayamos a lo esencial.

Primero, Angular no reemplaza a jQuery

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

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

Si usa jQuery, no debería rociarlo por todas partes. El lugar correcto para la manipulación DOM en AngularJS es en una directiva. Más sobre esto más adelante.

JavaScript discreto con selectores versus plantillas declarativas

jQuery generalmente se aplica discretamente. Su código JavaScript está vinculado en el encabezado (o 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á en control. El HTML tiene una existencia completamente independiente. Su HTML sigue siendo semántico incluso sin JavaScript. Los atributos de Onclick son muy malas prácticas.

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 del compilador) y son una de las principales formas en que la plantilla se engancha al modelo.

Cuando vea esto por primera vez, podría verse tentado a escribir AngularJS como JavaScript intrusivo de la vieja escuela (como lo hice al principio). De hecho, AngularJS no cumple con esas reglas. En AngularJS, su 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 para ser manipulado. Para AngularJS, su HTML es el código que se compilará. AngularJS lee en toda su página web y literalmente lo compila en una nueva página web utilizando su compilador incorporado.

Su plantilla debe ser declarativa; su significado debe quedar claro simplemente al leerlo. Utilizamos atributos personalizados con nombres significativos. Creamos nuevos elementos HTML, nuevamente con nombres significativos. Un diseñador con un conocimiento mínimo de HTML y sin habilidad de codificación puede leer su plantilla AngularJS y comprender lo que está haciendo. Él o ella pueden hacer modificaciones. Este es el camino 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 he escrito JavaScript y, sin embargo, tengo todo este comportamiento. La respuesta es obvia. Debido a que AngularJS compila el DOM, AngularJS está tratando su HTML como código. Para muchos casos simples, a menudo es suficiente escribir una plantilla y dejar que AngularJS la compile en una aplicación para usted.

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

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

Esta es una inversión radical de control a la que lleva un tiempo 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 conectar los componentes entre sí. Esta también es la forma angular.

HTML semántico frente a 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 permanecerá accesible.

Porque AngularJS trata su página HTML como una plantilla. Se supone que la plantilla no es 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 compilado son semánticos.

En AngularJS, lo que significa vidas en el modelo, el HTML es solo una plantilla, solo para visualización.

En este punto, es probable que tenga todo tipo de preguntas sobre 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 contenido AJAXed . Sin embargo, querrá asegurarse de que está utilizando URL de estado de inserción y que tiene 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

La separación de preocupaciones (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 del navegador. Se parece a esto:

  1. HTML: significado semántico. El HTML debe estar solo.
  2. CSS: estilo, sin el CSS, la página sigue siendo legible.
  3. JavaScript - Comportamiento, sin el script el contenido permanece.

Nuevamente, AngularJS no cumple con sus reglas. De un solo golpe, 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 suelen ser objetos JSON . Los modelos existen como atributos de un objeto llamado $ scope. También puede almacenar prácticas funciones de utilidad en $ scope a las que pueden acceder sus plantillas.
  2. Ver: sus vistas están escritas 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 conecta la vista al modelo. Su función es inicializar $ scope. Dependiendo de su aplicación, es posible que necesite o no 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 adelante.

Si, como yo, viviste la guerra de los navegadores, es posible que esta idea sea bastante ofensiva. Supéralo, valdrá la pena, lo prometo.

Complementos vs. Directivas

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

En jQuery definimos complementos agregando funciones al jQuery.prototype. Luego los conectamos al DOM seleccionando elementos y llamando al complemento en 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, tal vez envuelta en un elemento de navegación. Luego, puede escribir un poco de jQuery para seleccionar la lista en la página y rediseñarla 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 debe buscar y qué cambios hacer en ellos. Las directivas se conectan a la plantilla utilizando atributos o elementos, que usted inventa. La idea es ampliar las capacidades de HTML con nuevos atributos y elementos.

La forma AngularJS es extender las capacidades de HTML de aspecto nativo. Debe escribir HTML que se parezca a HTML, extendido con atributos y elementos personalizados.

Si desea un carrusel, simplemente use un <carousel />elemento, luego defina una directiva para extraer una plantilla y haga que ese tonto funcione.

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

La tendencia con jQuery es escribir grandes complementos grandes como lightbox que luego configuramos pasando numerosos valores y opciones.

Esto es un error en AngularJS.

Tome el ejemplo de un menú desplegable. Al escribir un complemento desplegable, puede tener la tentación de codificar en controladores de clics, tal vez una función para agregar un galón que esté 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.

Digamos que tiene un menú que desea desplegar al pasar el mouse sobre él. Bueno, ahora tenemos un problema. Nuestro complemento se ha conectado en nuestro controlador de clics, necesitaremos 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 plegado y proporcionar métodos para plegar (), 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 al pasar el mouse?

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

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

Cierre vs. $ alcance

Los complementos de 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. Realmente solo tiene acceso al conjunto de nodos DOM pasados ​​al complemento por jQuery, más cualquier variable local definida en el cierre y cualquier global que haya 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 difícil.

AngularJS tiene objetos $ scope. Estos son objetos especiales creados y mantenidos por AngularJS en los que almacena su modelo. Ciertas directivas generarán un nuevo $ scope, que por defecto hereda de su envoltorio $ scope usando la herencia prototípica de JavaScript. Se puede acceder al objeto $ scope en el controlador y la vista.

Esta es la parte inteligente. Debido a que la estructura de la herencia de $ alcance sigue aproximadamente la estructura del DOM, los elementos tienen acceso a su propio alcance, y a cualquier ámbito que contenga sin problemas, hasta el $ alcance 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 menú desplegable $ scope debe saberlo. Si el usuario actualiza sus preferencias, es posible que desee actualizar el alcance global $, y cualquier ámbito anidado que escuche las preferencias del usuario será alertado automáticamente.

Esto puede sonar complicado, de hecho, una vez que te relajas, es como volar. No necesita crear el objeto $ scope, AngularJS lo instancia y configura por usted, de manera correcta y apropiada según la jerarquía de su plantilla. AngularJS 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 versus enlace de datos

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

En AngularJS también puede hacerlo, pero le recomendamos que utilice el enlace de datos. Cambie su modelo, y debido a que el DOM está vinculado a él a través de una plantilla, su 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 sobrecarga cognitiva asociada, 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>

mostrará el nombre de usuario en un párrafo. Es un enlace en vivo, por lo que si el $scope.user.namevalor se actualiza, la plantilla también se actualizará.

Ajax todo el tiempo

En jQuery, hacer una llamada Ajax es bastante simple, pero aún es algo en lo que podrías pensar dos veces. Hay una complejidad adicional en la que pensar, y una buena parte del guión que mantener.

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

Objetos de servicio frente a funciones auxiliares

En jQuery, si queremos realizar una pequeña tarea no relacionada con dom, como extraer un feed de una API, podríamos escribir una pequeña función para hacerlo en nuestro cierre. Esa es una solución válida, pero ¿qué pasa si queremos acceder a ese feed a menudo? ¿Qué pasa 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 singletons, lo que significa que nunca puede haber más de uno. Supongamos que queremos acceder a la API de desbordamiento de pila, podríamos escribir una StackOverflowServiceque defina los métodos para hacerlo.

Digamos que tenemos un carrito de compras. Podríamos definir un ShoppingCartService que mantiene nuestro carrito y contiene métodos para agregar y eliminar artículos. Debido a que el servicio es un singleton y es compartido por todos los demás componentes, cualquier objeto que necesite puede escribir en el carrito de compras y extraer datos de él. Siempre es el mismo carrito.

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

Inyección de dependencia (DI) vs. Instatiation - también conocido como desespaguetificación

AngularJS gestiona tus dependencias por ti. Si desea un objeto, simplemente consúltelo y AngularJS lo obtendrá por usted.

Hasta que empiece a usar esto, es difícil explicar qué tan enorme es la bendición del tiempo. Nada como AngularJS DI existe dentro de jQuery.

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

Digamos que tengo un componente llamado 'FlickrService' que define 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 él por este nombre:

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 de las cosas sea muy fácil, y prácticamente elimina cualquier tendencia a la spagettificación. Tenemos una lista plana de componentes, y AngularJS nos los entrega uno por uno a medida que los necesitamos.

Arquitectura de servicio modular.

jQuery dice muy poco sobre cómo debe organizar su código. AngularJS tiene opiniones.

AngularJS le proporciona módulos en los que puede colocar su código. Si está escribiendo una secuencia de comandos que habla con Flickr, por ejemplo, es posible que desee crear un módulo Flickr para envolver 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 debe incluir todos los demás módulos de los que dependerá su aplicación.

Obtiene una reutilización de código simple, si desea escribir otra aplicación basada en Flickr, simplemente puede incluir el módulo 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 están disponibles para nosotros como una lista simple identificada por sus cadenas únicas . 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 está utilizando bien AngularJS (plantillas, enlace de datos, $ scope, directivas, etc.), encontrará que necesita mucho menos jQuery de lo que podría necesitar.

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

Piense menos en JavaScript discreto y, en cambio, piense en términos de extensiones HTML.

Mi librito

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


66
La idea de que "Separación de preocupaciones" es diferente de "MVC (Modelo, Vista, Controlador)" es completamente falsa. El modelo de idiomas web de separación de preocupaciones (HTML, CSS y JS) lo hace permitiendo que las personas coloquen cosas en una página web (el marcado / HTML) sin importar cómo se ve (estilo / diseño / CSS) o lo que "hace" (Eventos DOM / AJAX / JavaScript). MVC también separa las preocupaciones. Cada "capa" en el patrón MVC tiene una función distinta: datos, enrutamiento / lógica o representación. Las capas están unidas por devoluciones de llamada, rutas y enlaces de modelos. En teoría, una persona puede especializarse en cada capa, que suele ser el caso.

Como alguien proveniente de un entorno estricto de SOC, y como un defensor de larga data de los estándares web que se remontan a las guerras de los navegadores, inicialmente encontré problemáticas las plantillas no semánticas y no validadoras de Angular. Solo quería dejar en claro que para escribir Angular es necesario dejar el SOC, ya que generalmente se practica. Esto puede ser una transición difícil.
superluminary

Estás en lo correcto. SOC es un término amplio, pero en el mundo web SOC tiene (o posiblemente tuvo) un significado muy específico: HTML semántico, CSS presentacional y JavaScript para el comportamiento. Estoy haciendo algunas suposiciones sobre mi audiencia que tal vez no sean razonables, por lo que también debería disculparme.
superluminario el

Encuentro su respuesta más clara e iluminadora. Soy un novato aquí, entonces, si tengo una extensión para cambiar una página existente (que no controlo), ¿debería mantener JQuery entonces?
Daniel Möller

152

¿Puedes describir el cambio de paradigma que es necesario?

Imperativo vs declarativo

Con jQuery le dices al DOM lo que debe suceder, paso a paso. Con AngularJS, usted describe qué resultados 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 utiliza el patrón MVC (consulte su representación gráfica ). Se centra en gran medida en la separación de las preocupaciones.

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

jQuery es una biblioteca

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

Se centra en la separación de preocupaciones y pruebas (pruebas unitarias y pruebas de extremo a extremo), lo que facilita el desarrollo basado en pruebas.

La mejor manera de comenzar es a través de su increíble tutorial . Puedes seguir los pasos en un par de horas; sin embargo, en caso de que desee dominar los conceptos detrás de escena, incluyen una miríada de referencias para lecturas adicionales.

¿Hay alguna consideración / restricción 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 enfoque RESTful .

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


27
Creo que estás enturbiando las aguas al hablar de cómo jQuery es una "biblioteca" y Angular es un "marco" ... por un lado, creo que es posible argumentar que jQuery es un marco ... es una abstracción de manipulación DOM y manejo de eventos. Puede que no sea un marco para el mismo tipo de cosas que Angular es, pero ese es el dilema en el que se encuentra el que hace la pregunta: realmente no saben la diferencia entre Angular y jQuery, y por lo que el interlocutor sabe, jQuery es un marco para construir sitios web pesados ​​para el cliente. Así que discutir sobre terminología no aclarará las cosas.
Zando

15
Creo que tú eres el que se está confundiendo. Esta pregunta aborda exactamente este stackoverflow.com/questions/7062775 . Además, esta respuesta puede ayudar a aclarar cuál es la diferencia entre un marco y una biblioteca: stackoverflow.com/a/148759/620448
Ulises

66
Una biblioteca no se convierte en un "marco" solo porque su colección de funciones es especialmente útil o grande. Un marco toma decisiones por ti. Cuando comienzas a usar AngularJS, es probable que te acople por su naturaleza. (Por ejemplo: solo debe actualizar el DOM en las directivas, de lo contrario, algo se estropeará). Esto se debe a que AngularJS es un marco. Cuando usa jQuery, puede mezclar y combinar herramientas con relativa facilidad con un riesgo mínimo de conflicto. Esto se debe a que jQuery es una biblioteca, y al menos medio decente, también.

8
Una biblioteca es el código al que llamas. Un marco es un código que llama a su código. Según esta definición, Angular es un marco. Usted le proporciona componentes y Angular se encarga de que sus componentes se instancian con las dependencias que necesitan.
superluminary

84

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

AngularJS cambia la forma de encontrar elementos

En jQuery , normalmente usa selectores para buscar elementos y luego los conecta:
$('#id .class').click(doStuff);

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

AngularJS no necesita (o quiere) a encontrar los elementos que utilizan selectores - la principal diferencia entre AngularJS de jqLite frente en toda regla jQuery es que jqLite no soporta selectores .

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


13
Solo como descargo de responsabilidad, hay MUCHAS diferencias más importantes entre Angular y jQuery. Pero encontrar elementos es el que requiere el mayor cambio de pensamiento.
Scott Rippey

1
perdóname si me equivoco, pero pensé que un selector era lo que usabas para encontrar el elemento DOM. ¿Prefiere mantener cada parte de su IU recién cargada como referencia, en lugar de simplemente seleccionar uno o 2 elementos en los que un usuario puede hacer clic sobre la marcha utilizando un selector? suena más difícil para mí ..
RozzA

3
@AlexanderPritchard El objetivo de Angular es que no selecciona de su JavaScript, sino que lo dirige desde su plantilla. Es una inversión de control que pone el poder en manos del diseñador. Este es un principio de diseño deliberado. Para realmente obtener Angular, debe estar pensando en su código de esta manera. Es un cambio difícil de hacer.
superluminary

3
@superluminary ¡Qué gran cita! "no seleccione; directo!" En serio, voy a usar eso.
Scott Rippey

1
Esta es una de mis cosas favoritas sobre AngularJS. No tengo que preocuparme de que el equipo de UX rompa mi funcionalidad o que yo rompa sus estilos. Usan clases, yo uso directivas, punto. No echo de menos los selectores un poco.
adam0101

69

jQuery

jQuery crea comandos de JavaScript ridículamente largos, como getElementByHerpDerpun navegador más corto y 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 fue diseñado para páginas estáticas).

Editar:

Al decir "Tengo experiencia en jQuery, ¿cómo pienso en AngularJS?" es como decir "Tengo un fondo HTML, ¿cómo pienso en JavaScript?" El hecho de que esté haciendo la pregunta muestra que lo más probable es que no entienda 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 que dice "AngularJS usa directivas mientras que jQuery usa selectores 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>todo el lugar solo para hacer una aplicación. Hace que HTML realmente funcione para aplicaciones en lugar de para lo que fue diseñado, que es páginas web estáticas y educativas. Lo logra de una manera indirecta usando JavaScript, pero fundamentalmente es una extensión de HTML, no JavaScript.


@Robert depende de lo que estés haciendo. $(".myclass")es extremadamente común, y más que un poco más fácil en jQuery que PO-Javascript.
Rob Grant

61

jQuery: piensa mucho en 'CONSULTAR 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 desea mostrar en algún formato en el DOM, en jQuery, necesita '1. ENCONTRAR 'donde en el DOM desea colocar estos datos, el' 2. ACTUALIZAR / APROBAR 'allí creando un nuevo nodo o simplemente configurando 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, todo hecho dentro del mismo contexto de obtención y formateo de datos del servidor, se ha ido 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 ' No tengo que pensarlo. 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 CSS, es decir, dónde está divo tdqué tiene una clase o atributo, etc., para que pueda obtener su HTML o color o valor, pero en AngularJS, te encontrarás pensando así: con qué modelo estoy tratando, estableceré el valor del modelo en verdadero. No se molesta si la vista que refleja este valor es una casilla marcada o si reside en un tdelemento (detalles que a menudo habría tenido que pensar en jQuery).

Y con la manipulación DOM en AngularJS, te encuentras agregando directivas y filtros, que puedes considerar como extensiones HTML válidas.

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, por lo 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 de AngularJS un marco en lugar de una biblioteca.


46

Esas son algunas respuestas muy agradables, pero largas.

Para resumir mis experiencias:

  1. Los controladores y proveedores (servicios, fábricas, etc.) son para modificar el modelo de datos, NO HTML.
  2. El HTML y las directivas definen el diseño y el enlace al modelo.
  3. Si necesita compartir datos entre controladores, cree un servicio o una fábrica; son elementos únicos que se comparten en la aplicación.
  4. Si necesita un widget HTML, cree una directiva.
  5. Si tiene algunos datos y ahora está tratando de actualizar HTML ... ¡DETÉNGASE! actualice el modelo y asegúrese de que su HTML esté vinculado al modelo.

45

jQuery es una biblioteca de manipulación DOM.

AngularJS es un framework MV *.

De hecho, AngularJS es uno de los pocos frameworks JavaScript MV * (muchas herramientas JavaScript MVC aún se incluyen en la biblioteca de categorías).

Al ser un marco, aloja su código y toma las decisiones sobre qué llamar y cuándo.

AngularJS en sí incluye una edición jQuery-lite dentro de él. Entonces, para algunas selecciones / manipulaciones DOM básicas, realmente no tiene que incluir la biblioteca jQuery (ahorra muchos bytes para ejecutarse en la red).

AngularJS tiene el concepto de "Directivas" para la manipulación de DOM y el diseño de componentes de IU reutilizables, por lo que debe usarlo siempre que sienta la necesidad de hacer cosas relacionadas con la manipulación de DOM (las directivas son solo el lugar donde debe escribir el código jQuery mientras usa AngularJS).

AngularJS implica alguna curva de aprendizaje (más que jQuery :-).

-> Para cualquier desarrollador que venga de jQuery, mi primer consejo sería "aprender JavaScript como un lenguaje de primera clase antes de saltar a un marco rico como AngularJS". Aprendí el hecho anterior de la manera difícil.

Buena suerte.


34

Son manzanas y naranjas. No quieres compararlos. Son dos cosas diferentes. AngularJs ya tiene incorporado jQuery lite que le permite realizar la manipulación básica del DOM sin siquiera incluir la versión completa de jQuery.

jQuery tiene que ver con la manipulación DOM. Resuelve todo el dolor del navegador cruzado de lo contrario tendrá que lidiar, pero no es un marco que le permita dividir su aplicación en componentes como AngularJS.

Lo bueno de AngularJs es que le permite separar / aislar la manipulación DOM en las directivas. Hay directivas integradas listas para su uso, como ng-click. Puede crear sus propias directivas personalizadas que contendrán toda su lógica de vista o manipulación DOM para que no termine mezclando el código de manipulación DOM en los controladores o servicios que deben ocuparse de la lógica empresarial.

Angular desglosa su aplicación en - Controladores - Servicios - Vistas - etc.

y hay una cosa más, esa es la directiva. Es un atributo que puede adjuntar a cualquier elemento DOM y puede volverse loco con jQuery dentro de él sin preocuparse de que su jQuery entre en conflicto con los componentes de AngularJs o se equivoque con su arquitectura.

Escuché en una reunión a la que asistí, uno de los fundadores de Angular dijo que trabajaron muy duro para separar la manipulación del DOM, así que no intentes incluirlos nuevamente.


31

Escuche el podcast JavaScript Jabber: Episodio # 32 que presenta a los creadores originales de AngularJS: Misko Hevery e Igor Minar. Hablan mucho sobre cómo es llegar a AngularJS desde otros fondos de JavaScript, especialmente jQuery.

Uno de los puntos destacados en el podcast hizo que muchas cosas hagan clic para mí con respecto a su pregunta:

MISKO : [...] una de las cosas en las que pensamos muy poco en Angular es cómo proporcionamos muchas trampillas de escape para que pueda salir y, básicamente, encontrar una forma de salir de esto. Entonces, para nosotros, la respuesta es esta cosa llamada "Directivas". Y con las directivas, esencialmente te conviertes en un pequeño JavaScript regular de jQuery, puedes hacer lo que quieras.

IGOR : Piensa en la directiva como la instrucción para el compilador que le dice cada vez que te encuentras con este cierto elemento o este CSS en la plantilla, y mantienes este tipo de código y ese código está a cargo del elemento y todo lo que está debajo de ese elemento en el árbol DOM

Una transcripción de todo el episodio está disponible en el enlace proporcionado anteriormente.

Entonces, para responder directamente a su pregunta: AngularJS es muy obstinado y es un verdadero framework MV *. Sin embargo, aún puede hacer todas las cosas realmente geniales que conoce y ama con jQuery dentro de las directivas. No se trata de "¿Cómo hago lo que solía hacer en jQuery?" tanto como es cuestión de "¿Cómo suplemento AngularJS con todas las cosas que solía hacer en jQuery?"

Realmente son dos estados mentales muy diferentes.


2
No estoy seguro de estar completamente de acuerdo en que Angular es MUY obstinado. Si quieres ser obstinado, mira a Ember. Describiría que Angular tiene opiniones de Ricitos de Oro: por mucho de lo que veo, jQuery tiene muy pocas opiniones y Ember tiene demasiadas. Angular parece justo.
fool4jesus

30

Encuentro esta pregunta interesante, porque mi primera exposición seria a la programación de JavaScript fue Node.js y AngularJS. Nunca aprendí jQuery, y supongo que es algo bueno, porque no tengo que desaprender nada. De hecho, evito activamente las soluciones de jQuery para mis problemas y, en cambio, solo busco una "forma AngularJS" para resolverlos. Por lo tanto, supongo que mi respuesta a esta pregunta se reduciría esencialmente a "pensar como alguien que nunca aprendió jQuery" y evitar cualquier tentación de incorporar jQuery directamente (obviamente, AngularJS lo usa en cierta medida detrás de escena).


23

AngularJS y jQuery:

AngularJs y JQuery son completamente diferentes en todos los niveles, excepto la funcionalidad JQLite y lo verá una vez que comience a aprender las características principales de AngularJs (lo expliqué a continuación).

AngularJs es un marco del lado del cliente que ofrece construir la aplicación independiente del lado del cliente. JQuery es una biblioteca del lado del cliente que juega alrededor del DOM.

Principio de AngularJs Cool: si desea algunos cambios en su interfaz de usuario, piense desde la perspectiva del cambio de datos del modelo. Cambie sus datos y la IU se volverá a representar. No necesita jugar DOM cada vez, a menos y hasta que apenas sea necesario y eso también debe manejarse a través de las directivas angulares.

Para responder a esta pregunta, quiero compartir mi experiencia en la primera aplicación empresarial con AngularJS. Estas son las características más asombrosas que Angular proporciona cuando comenzamos a cambiar nuestra mentalidad jQuery y obtenemos Angular como un marco y no la biblioteca.

El enlace de datos bidireccional es sorprendente: tenía una cuadrícula con todas las funciones ACTUALIZAR, BORRAR, INSERTAR. Tengo un objeto de datos que une el modelo de la cuadrícula usando ng-repeat. Solo necesita escribir una sola línea de código JavaScript simple para eliminar e insertar y eso es todo. La cuadrícula se actualiza automáticamente a medida que el modelo de cuadrícula cambia instantáneamente. La funcionalidad de actualización es en tiempo real, no hay código para ello. ¡¡¡Te sientes increíble!!!

Las directivas reutilizables son excelentes: escriba directivas en un solo lugar y úselas en toda la aplicación. ¡¡¡DIOS MIO!!! Usé estas directivas para paginación, expresiones regulares, validaciones, etc. ¡Es realmente genial!

El enrutamiento es sólido: depende de su implementación cómo desea usarlo, pero requiere muy pocas líneas de código para enrutar la solicitud para especificar HTML y controlador (JavaScript)

Los controladores son geniales: los controladores se encargan de su propio HTML, pero esta separación también funciona bien para la funcionalidad común. Si desea llamar a la misma función con solo hacer clic en un botón en HTML maestro, simplemente escriba el mismo nombre de función en cada controlador y escriba un código individual.

Complementos: hay muchas otras características similares, como mostrar una superposición en su aplicación. No necesita escribir código para ello, solo use un complemento de superposición disponible como wc-overlay, y esto se encargará automáticamente de todas las solicitudes XMLHttpRequest (XHR).

Ideal para arquitectura RESTful : ser un framework completo hace que AngularJS sea ideal para trabajar con una arquitectura RESTful. Llamar a las API REST CRUD es muy fácil y

Servicios : escriba códigos comunes utilizando servicios y menos código en los controladores. Los servicios se pueden usar para compartir funcionalidades comunes entre los controladores.

Extensibilidad : Angular ha extendido las directivas HTML utilizando directivas angulares. Escribe expresiones dentro de html y evalúalas en tiempo de ejecución. Cree sus propias directivas y servicios y úselos en otro proyecto sin ningún esfuerzo adicional.


20

Como principiante de JavaScript MV * y centrado exclusivamente en la arquitectura de la aplicación (no en el lado del servidor / cliente), sin duda recomendaría el siguiente recurso (que me sorprende que aún no se haya mencionado): Patrones de diseño de JavaScript , por Addy Osmani , como introducción a diferentes patrones de diseño de JavaScript . Los términos utilizados en esta respuesta se toman del documento vinculado anterior. No voy a repetir lo que fue redactado realmente bien en la respuesta aceptada. En cambio, esta respuesta se vincula con los antecedentes teóricos que impulsan AngularJS (y otras bibliotecas).

Al igual que yo, se dará cuenta rápidamente de que AngularJS (o Ember.js , Durandal y otros frameworks MV * para el caso) es un marco complejo que ensambla muchos de los diferentes patrones de diseño de JavaScript.

También me resultó más fácil probar (1) código JavaScript nativo y (2) bibliotecas más pequeñas para cada uno de estos patrones por separado antes de sumergirme en un marco global. Esto me permitió comprender mejor qué cuestiones cruciales aborda un marco (porque usted se enfrenta personalmente al problema).

Por ejemplo:

  • Programación orientada a objetos JavaScript (este es un enlace de búsqueda de Google). No es una biblioteca, pero ciertamente es un requisito previo para la programación de cualquier aplicación. Me enseñó las implementaciones nativas de los patrones de prototipo, constructor, singleton y decorador.
  • jQuery / Underscore para el patrón de fachada (como WYSIWYG para manipular el DOM)
  • Prototype.js para el patrón prototype / constructor / mixin
  • RequireJS / Curl.js para el patrón de módulo / AMD
  • KnockoutJS para el patrón observable de publicación / suscripción

NB: Esta lista no está completa, ni 'las mejores bibliotecas'; Simplemente son las bibliotecas que utilicé. Estas bibliotecas también incluyen más patrones, los mencionados son solo sus focos principales o intenciones originales. Si siente que falta algo en esta lista, sírvase mencionarlo en los comentarios, y me complacerá agregarlo.


12

En realidad, si está utilizando AngularJS, ya no necesita jQuery. AngularJS tiene el enlace y la directiva, que es un muy buen "reemplazo" para la mayoría de las cosas que puede hacer con jQuery.

Normalmente desarrollo aplicaciones móviles con AngularJS y Cordova . Lo ÚNICO de jQuery que necesitaba es el Selector.

Al buscar en Google, veo que hay un módulo selector jQuery independiente. Es chisporroteo.

Y decidí hacer un pequeño fragmento de código que me ayudara a iniciar rápidamente un sitio web usando AngularJS con el poder de jQuery Selector (usando Sizzle).

Compartí mi código aquí: https://github.com/huytd/Sizzular

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.