"Pensare in AngularJS" se ho uno sfondo jQuery? [chiuso]


4514

Supponiamo che abbia familiarità con lo sviluppo di applicazioni lato client in jQuery , ma ora vorrei iniziare a utilizzare AngularJS . Puoi descrivere il cambio di paradigma necessario? Ecco alcune domande che potrebbero aiutarti a inquadrare una risposta:

  • Come posso progettare e progettare le applicazioni Web sul lato client in modo diverso? Qual è la differenza più grande?
  • Cosa dovrei smettere di fare / usare; Cosa dovrei iniziare a fare / usare invece?
  • Ci sono considerazioni / restrizioni sul lato server?

Non sto cercando un confronto dettagliato tra jQuerye AngularJS.


Per coloro che hanno familiarità con "ASP.NET MVC" o "RoR", basti pensare ad Angular come a "client lato MVC" e basta.
Serge Shultz,

Risposte:


7178

1. Non progettare la tua pagina, quindi modificarla con manipolazioni DOM

In jQuery, progetti una pagina e la rendi dinamica. Questo perché jQuery è stato progettato per aumentare ed è cresciuto incredibilmente da quella semplice premessa.

Ma in AngularJS, devi partire da zero con in mente la tua architettura. Invece di iniziare pensando "Ho questo pezzo di DOM e voglio farlo fare X", devi iniziare con quello che vuoi realizzare, quindi progettare la tua applicazione e infine progettare la tua vista.

2. Non aumentare jQuery con AngularJS

Allo stesso modo, non iniziare con l'idea che jQuery esegua X, Y e Z, quindi aggiungerò AngularJS per modelli e controller. Questo è davvero allettante quando hai appena iniziato, motivo per cui consiglio sempre ai nuovi sviluppatori di AngularJS di non usare affatto jQuery, almeno fino a quando non si abituano a fare le cose in "Angular Way".

Ho visto molti sviluppatori qui e sulla mailing list creare queste soluzioni elaborate con plugin jQuery di 150 o 200 righe di codice che poi incollano in AngularJS con una raccolta di callback e di messaggi $applyconfusi e contorti; ma alla fine riescono a farlo funzionare! Il problema è che nella maggior parte dei casi quel plugin jQuery potrebbe essere riscritto in AngularJS in una frazione del codice, dove improvvisamente tutto diventa comprensibile e semplice.

La linea di fondo è questa: quando si risolve, prima "pensare in AngularJS"; se non riesci a pensare a una soluzione, chiedi alla community; se dopo tutto questo non esiste una soluzione facile, quindi sentitevi liberi di raggiungere per il jQuery. Ma non lasciare che jQuery diventi una stampella o non dominerai mai AngularJS.

3. Pensa sempre in termini di architettura

Per prima cosa sappi che le applicazioni a pagina singola sono applicazioni . Sono non pagine web. Quindi dobbiamo pensare come uno sviluppatore sul lato server oltre a pensare come uno sviluppatore sul lato client. Dobbiamo pensare a come dividere la nostra applicazione in singoli componenti estensibili e testabili.

Quindi come lo fai? Come "pensi in AngularJS"? Ecco alcuni principi generali, in contrasto con jQuery.

Il punto di vista è il "record ufficiale"

In jQuery, modifichiamo la vista a livello di codice. Potremmo avere un menu a discesa definito come un ulsimile:

<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>

In jQuery, nella nostra logica applicativa, lo attiveremmo con qualcosa del tipo:

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

Quando guardiamo semplicemente la vista, non è immediatamente ovvio che ci sia qualche funzionalità qui. Per piccole applicazioni, va bene. Ma per applicazioni non banali, le cose diventano rapidamente confuse e difficili da mantenere.

In AngularJS, tuttavia, la vista è la registrazione ufficiale della funzionalità basata sulla vista. La nostra uldichiarazione sarebbe simile a questa invece:

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

Questi due fanno la stessa cosa, ma nella versione di AngularJS chiunque guardi il modello sa cosa dovrebbe succedere. Ogni volta che entra a far parte un nuovo membro del team di sviluppo, può guardare a questo e poi sapere che esiste una direttiva chiamata dropdownMenuoperando su di esso; non ha bisogno di intuire la risposta giusta o vagliare alcun codice. La vista ci ha detto cosa doveva succedere. Molto più pulito.

Gli sviluppatori che non conoscono AngularJS spesso pongono una domanda del tipo: come posso trovare tutti i collegamenti di un tipo specifico e aggiungere una direttiva su di essi. Lo sviluppatore è sempre sbalordito quando rispondiamo: tu no. Ma la ragione per cui non lo fai è che questo è come metà jQuery, metà AngularJS e non va bene. Il problema qui è che lo sviluppatore sta provando a "fare jQuery" nel contesto di AngularJS. Non funzionerà mai bene. La vista è il record ufficiale. Al di fuori di una direttiva (ne parleremo più avanti), non cambierete mai e poi mai il DOM. E le direttive vengono applicate nella vista , quindi l'intento è chiaro.

Ricorda: non progettare e quindi segnare. Devi progettare, quindi progettare.

Associazione dati

Questa è di gran lunga una delle caratteristiche più straordinarie di AngularJS e elimina molto la necessità di fare i tipi di manipolazioni DOM che ho citato nella sezione precedente. AngularJS aggiornerà automaticamente la tua vista in modo da non doverlo fare! In jQuery, rispondiamo agli eventi e quindi aggiorniamo i contenuti. Qualcosa di simile a:

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

Per una vista simile a questa:

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

Oltre a mescolare le preoccupazioni, abbiamo anche gli stessi problemi di intento che ho menzionato prima. Ma soprattutto, abbiamo dovuto fare riferimento e aggiornare manualmente un nodo DOM. E se vogliamo eliminare una voce di registro, anche per questo dobbiamo codificare il DOM. Come testiamo la logica oltre al DOM? E se volessimo cambiare la presentazione?

Questo è un po 'disordinato e un po' fragile. Ma in AngularJS, possiamo farlo:

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

E la nostra visione può assomigliare a questa:

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

Tuttavia, il nostro punto di vista potrebbe assomigliare a questo:

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

E ora invece di utilizzare un elenco non ordinato, stiamo usando le caselle di avviso Bootstrap. E non abbiamo mai dovuto cambiare il codice del controller! Ma soprattutto, indipendentemente da dove o come viene aggiornato il registro, anche la vista cambierà. Automaticamente. ! Neat

Anche se non l'ho mostrato qui, l'associazione dei dati è bidirezionale. Così quei messaggi di log potrebbe anche essere modificabile nella vista solo in questo modo: <input ng-model="entry.msg" />. E c'era molta gioia.

Livello del modello distinto

In jQuery, il DOM è un po 'come il modello. Ma in AngularJS, abbiamo un livello di modello separato che possiamo gestire come vogliamo, in modo completamente indipendente dalla vista. Questo aiuta per l'associazione dei dati di cui sopra, mantiene la separazione delle preoccupazioni e introduce una testabilità molto maggiore. Altre risposte hanno menzionato questo punto, quindi lo lascerò a quello.

Separazione degli interessi

E tutto quanto sopra si lega a questo tema generale: tieni separate le tue preoccupazioni. La tua visione funge da registrazione ufficiale di ciò che dovrebbe accadere (per la maggior parte); il tuo modello rappresenta i tuoi dati; hai un livello di servizio per eseguire attività riutilizzabili; fai manipolazione DOM e aumenti la tua visione con direttive; e incollalo tutto insieme ai controller. Ciò è stato menzionato anche in altre risposte e l'unica cosa che aggiungerei riguarda la testabilità, di cui parlerò in un'altra sezione di seguito.

Iniezione di dipendenza

Per aiutarci con la separazione delle preoccupazioni è l' iniezione di dipendenza (DI). Se provieni da un linguaggio lato server (da Java a PHP ) probabilmente hai già familiarità con questo concetto, ma se sei un ragazzo lato client proveniente da jQuery, questo concetto può sembrare qualsiasi cosa, da sciocco a superfluo a hipster . Ma non lo è. :-)

Da una prospettiva ampia, DI significa che puoi dichiarare i componenti molto liberamente e poi da qualsiasi altro componente, basta chiedere un'istanza di esso e verrà concesso. Non devi conoscere l'ordine di caricamento, i percorsi dei file o qualcosa del genere. La potenza potrebbe non essere immediatamente visibile, ma fornirò solo un esempio (comune): test.

Diciamo nella nostra applicazione, abbiamo bisogno di un servizio che implementa l'archiviazione sul lato server tramite un'API REST e, a seconda dello stato dell'applicazione, anche l'archiviazione locale. Quando eseguiamo test sui nostri controller, non vogliamo comunicare con il server , dopotutto stiamo testando il controller . Possiamo semplicemente aggiungere un servizio simulato con lo stesso nome del nostro componente originale e l'iniettore assicurerà che il nostro controller ottenga automaticamente quello falso - il nostro controller non lo fa e non è necessario che conosca la differenza.

A proposito di test ...

4. Sviluppo test-driven - sempre

Questo fa davvero parte della sezione 3 sull'architettura, ma è così importante che la sto mettendo come propria sezione di livello superiore.

Di tutti i plug-in jQuery che hai visto, usato o scritto, quanti di loro avevano una suite di test di accompagnamento? Non molti perché jQuery non è molto disponibile. Ma AngularJS lo è.

In jQuery, l'unico modo per testare è spesso quello di creare il componente in modo indipendente con una pagina di esempio / demo su cui i nostri test possono eseguire la manipolazione del DOM. Quindi dobbiamo sviluppare un componente separatamente e quindi integrarlo nella nostra applicazione. Che inconveniente! Per la maggior parte del tempo, quando si sviluppa con jQuery, optiamo per uno sviluppo iterativo anziché test-driven. E chi potrebbe biasimarci?

Ma poiché abbiamo una separazione delle preoccupazioni, possiamo fare lo sviluppo guidato dai test in modo iterativo in AngularJS! Ad esempio, supponiamo che desideriamo che una direttiva semplicissima indichi nel nostro menu quale sia il nostro percorso attuale. Possiamo dichiarare ciò che vogliamo in vista della nostra applicazione:

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

Bene, ora possiamo scrivere un test per la when-activedirettiva inesistente :

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();
}));

E quando eseguiamo il nostro test, possiamo confermare che fallisce. Solo ora dovremmo creare la nostra direttiva:

.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' );
                }
            });
        }
    };
});

Il nostro test ora passa e il nostro menu funziona come richiesto. Il nostro sviluppo è sia iterativo che test-driven. Wicked-cool.

5. Concettualmente, le direttive non sono confezionate con jQuery

Sentirai spesso "fare solo manipolazione DOM in una direttiva". Questa è una necessità Trattalo con la dovuta deferenza!

Ma tuffiamoci un po 'più a fondo ...

Alcune direttive semplicemente decorano ciò che è già nella vista (pensa ngClass) e quindi a volte eseguono subito la manipolazione del DOM e poi vengono sostanzialmente eseguite. Ma se una direttiva è come un "widget" e ha un modello, dovrebbe anche rispettare la separazione delle preoccupazioni. Cioè, il modello troppo dovrebbe rimanere in gran parte indipendenti dalla sua attuazione nelle funzioni di collegamento e del controller.

AngularJS viene fornito con un intero set di strumenti per renderlo molto semplice; con ngClasspossiamo aggiornare dinamicamente la classe; ngModelconsente l'associazione dati bidirezionale; ngShowe ngHidemostrare o nascondere a livello di codice un elemento; e molti altri - compresi quelli che scriviamo noi stessi. In altre parole, possiamo fare tutti i tipi di meraviglia senza manipolazione del DOM. Minore è la manipolazione del DOM, più facili saranno le direttive da testare, più facile sarà lo stile, più facile sarà cambiare in futuro e più saranno riutilizzabili e distribuibili.

Vedo molti sviluppatori nuovi ad AngularJS che usano le direttive come luogo per lanciare un sacco di jQuery. In altre parole, pensano "dato che non riesco a manipolare il DOM nel controller, prenderò quel codice per metterlo in una direttiva". Anche se certamente è molto meglio, spesso è ancora sbagliato .

Pensa al logger che abbiamo programmato nella sezione 3. Anche se lo inseriamo in una direttiva, vogliamo ancora farlo come "Angular Way". E ancora non si assume alcuna manipolazione del DOM! Ci sono molte volte in cui è necessaria la manipolazione del DOM, ma è molto più rara di quanto pensi! Prima di eseguire la manipolazione DOM ovunque nell'applicazione, chiediti se è davvero necessario. Potrebbe esserci un modo migliore.

Ecco un breve esempio che mostra lo schema che vedo più frequentemente. Vogliamo un pulsante commutabile. (Nota: questo esempio è un po 'inventato e uno skosh verboso per rappresentare casi più complicati che vengono risolti esattamente allo stesso modo.)

.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);
            });
        }
    };
});

Ci sono alcune cose che non vanno in questo:

  1. Innanzitutto, jQuery non è mai stato necessario. Qui non abbiamo fatto nulla che richiedesse assolutamente jQuery!
  2. Secondo, anche se abbiamo già jQuery sulla nostra pagina, non c'è motivo di usarlo qui; possiamo semplicemente usare angular.elemente il nostro componente continuerà a funzionare anche se inserito in un progetto che non ha jQuery.
  3. In terzo luogo, anche supponendo che jQuery fosse necessario per far funzionare questa direttiva, jqLite ( angular.element) utilizzerà sempre jQuery se è stato caricato! Quindi non abbiamo bisogno di usare il $- possiamo solo usare angular.element.
  4. Quarto, strettamente correlato al terzo, è che non è necessario racchiudere gli elementi jqLite $: il elementpassaggio alla linkfunzione sarebbe già un elemento jQuery!
  5. E quinto, che abbiamo menzionato nelle sezioni precedenti, perché stiamo mescolando elementi template nella nostra logica?

Questa direttiva può essere riscritta (anche per casi molto complicati!) Molto più semplicemente così:

.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;
            };
        }
    };
});

Ancora una volta, il modello è nel modello, quindi tu (o i tuoi utenti) potete facilmente sostituirlo con uno che soddisfi qualsiasi stile necessario e la logica non deve mai essere toccata. Riutilizzabilità: boom!

E ci sono ancora tutti quegli altri vantaggi, come i test: è facile! Indipendentemente dal contenuto del modello, l'API interna della direttiva non viene mai toccata, quindi il refactoring è semplice. Puoi cambiare il modello quanto vuoi senza toccare la direttiva. E indipendentemente da ciò che cambi, i test continuano comunque.

w00t!

Quindi se le direttive non sono solo raccolte di funzioni simili a jQuery, cosa sono? Le direttive sono in realtà estensioni di HTML . Se HTML non fa qualcosa di cui hai bisogno, scrivi una direttiva per farlo per te e poi lo usi come se facesse parte di HTML.

In altre parole, se AngularJS non fare qualcosa fuori dalla scatola, pensare a come la squadra avrebbe realizzarlo per adattarsi a destra dentro con ngClick, ngClasset al.

Sommario

Non usare nemmeno jQuery. Non includerlo nemmeno. Ti terrà indietro. E quando arrivate a un problema che pensate di sapere già come risolvere in jQuery, prima di raggiungere il $, provate a pensare a come farlo entro i confini di AngularJS. Se non lo sai, chiedi! 19 volte su 20, il modo migliore per farlo non ha bisogno di jQuery e per provare a risolverlo con jQuery si ottiene più lavoro per te.


204
Penso che integrare lavorando con JQuery all'interno di un'app angolare sia un caso d'uso importante a causa di tutti i plugin JQuery esistenti che sono stati scritti. Non sto riscrivendo FancyBox in jQuery per mantenere un'app Angolare pura.
Taudep,

119
@taudep Non credo che non siamo d'accordo tanto quanto pensi. La maggior parte dei plug-in jQuery può essere riscritta in AngularJS a buon mercato, e in quei casi dovremmo farlo. Per qualcosa di complesso per il quale non esiste un equivalente, allora provalo. Per citare dalla Sezione 2: 'La linea di fondo è questa: quando si risolve, prima "pensare in AngularJS"; se non riesci a pensare a una soluzione, chiedi alla community; se dopo tutto ciò non esiste una soluzione facile, sentiti libero di contattare jQuery . Ma non lasciare che jQuery diventi una stampella o non dominerai mai AngularJS. ' [enfasi aggiunta]
Josh David Miller,

67
un cinese si traduce in questa grande risposta, spero utile. hanzheng.github.io/tech/angularjs/2013/10/28/…
Han Zheng

18
@Benno Ciò che intende per "nessuna manipolazione del DOM" è che il codice della direttiva non esegue direttamente manipolazioni del DOM. Quel codice non sa nulla del DOM, sta solo modificando le variabili js nel tuo modello. Sì, il risultato finale è che il DOM viene modificato, ma perché al di fuori del codice che scriviamo, ci sono associazioni che reagiscono al cambiamento delle nostre variabili, ma all'interno della direttiva non ne sappiamo nulla, facendo una netta separazione tra manipolazione DOM e logica di business. Nel tuo esempio jQuery stai cambiando direttamente il DOM dicendo "aggiungi questo testo a questo elemento"
wired_in

11
@trusktr Se uno sviluppo imposta mai il valore di un elemento di input usando jQuery in un'applicazione AngularJS, sta commettendo un grave errore. L'unica sorta di eccezione a cui posso pensare è un plug-in jQuery esistente che è troppo difficile da trasferire e che modifica automaticamente un input, nel qual caso l'aggancio a un callback o l'impostazione di un watch è assolutamente essenziale per portare le modifiche in linea con l'applicazione.
Josh David Miller,

407

Imperativo → dichiarativo

In jQuery, i selettori vengono utilizzati per trovare elementi DOM e quindi associare / registrare i gestori di eventi. Quando si attiva un evento, quel codice (imperativo) viene eseguito per aggiornare / modificare il DOM.

In AngularJS, vuoi pensare alle viste piuttosto che agli elementi DOM. Le viste sono HTML (dichiarative) che contengono direttive AngularJS . Le direttive impostano i gestori di eventi dietro le quinte per noi e ci forniscono un database dinamico. I selettori sono usati raramente, quindi la necessità di ID (e alcuni tipi di classi) è notevolmente diminuita. Le viste sono legate ai modelli (tramite ambiti). Le viste sono una proiezione del modello. Gli eventi cambiano modelli (ovvero dati, proprietà dell'ambito) e le viste che proiettano tali modelli si aggiornano "automaticamente".

In AngularJS, pensa ai modelli, piuttosto che agli elementi DOM selezionati da jQuery che contengono i tuoi dati. Pensa alle visualizzazioni come alle proiezioni di quei modelli, piuttosto che alla registrazione di callback per manipolare ciò che l'utente vede.

Separazione degli interessi

jQuery utilizza JavaScript discreto : il comportamento (JavaScript) è separato dalla struttura (HTML).

AngularJS utilizza controller e direttive (ognuno dei quali può avere il proprio controller e / o funzioni di compilazione e collegamento) per rimuovere il comportamento dalla vista / struttura (HTML). Angular ha anche servizi e filtri per aiutarti a separare / organizzare la tua applicazione.

Vedi anche https://stackoverflow.com/a/14346528/215945

Progettazione dell'applicazione

Un approccio alla progettazione di un'applicazione AngularJS:

  1. Pensa ai tuoi modelli. Crea servizi o i tuoi oggetti JavaScript per quei modelli.
  2. Pensa a come presentare i tuoi modelli: le tue opinioni. Crea modelli HTML per ogni vista, usando le direttive necessarie per ottenere il database dinamico.
  3. Collegare un controller a ciascuna vista (utilizzando ng-view e routing o ng-controller). Chiedi al controller di trovare / ottenere solo i dati del modello necessari alla vista per svolgere il proprio lavoro. Rendi i controller il più sottili possibile.

Eredità prototipale

Puoi fare molto con jQuery senza sapere come funziona l'ereditarietà del prototipo JavaScript. Quando si sviluppano applicazioni AngularJS, si eviteranno alcune insidie ​​comuni se si ha una buona conoscenza dell'eredità JavaScript. Lettura consigliata: quali sono le sfumature dell'eredità prototipo / prototipica dell'ambito in AngularJS?


1
puoi pls. spiegare in che modo un elemento dom è diverso da una vista?
Rajkamal Subramanian,

22
@rajkamal, un elemento DOM è (ovviamente) un singolo elemento, e in jQuery questo è spesso ciò che selezioniamo / target / manipoliamo. Una vista angolare è una raccolta / modello di elementi DOM correlati: vista menu, vista intestazione, vista piè di pagina, vista barra laterale destra, vista profilo, forse più viste principali del contenuto (commutabili tramite ng-view). Fondamentalmente, si desidera suddividere le pagine in visualizzazioni diverse. Ogni vista ha il suo controller associato. Ogni vista proietta parte dei tuoi modelli.
Mark Rajcok,

3
jQuery NON è un imperativo. one whensono funzioni di ordine superiore, che operano sui membri di un oggetto raccolta jQuery.
Jack Viers,

18
Quindi per quale tipo di codice viene eseguito il callback on? Imperativo.
cwharris,

5
Questo imperativo contro dichiarativo è in realtà solo una questione di astrazioni. Alla fine, tutto il codice dichiarativo (cosa fare) viene implementato imperativamente (come farlo) o dallo sviluppatore in una subroutine a un livello di astrazione inferiore, dal framework o da un compilatore / interprete. Dire che "jQuery è un imperativo" in generale è un'affermazione piuttosto strana, soprattutto considerando che in realtà fornisce un'API molto più dichiarativa per quanto riguarda la manipolazione DOM "manuale".
Alex,

184

AngularJS vs. jQuery

AngularJS e jQuery adottano ideologie molto diverse. Se provieni da jQuery potresti trovare alcune delle differenze sorprendenti. L'angolare può farti arrabbiare.

Questo è normale, dovresti passare. Ne vale la pena.

La grande differenza (TLDR)

jQuery offre un toolkit per la selezione di bit arbitrari del DOM e per apportare modifiche ad hoc. Puoi fare praticamente tutto ciò che ti piace pezzo per pezzo.

AngularJS invece ti dà un compilatore .

Ciò significa che AngularJS legge l'intero DOM dall'alto verso il basso e lo tratta come codice, letteralmente come istruzioni per il compilatore. Mentre attraversa il DOM, cerca direttive specifiche ( direttive del compilatore) che indichino al compilatore AngularJS come comportarsi e cosa fare. Le direttive sono piccoli oggetti pieni di JavaScript che possono corrispondere a attributi, tag, classi o persino commenti.

Quando il compilatore angolare determina che un pezzo del DOM corrisponde a una particolare direttiva, chiama la funzione direttiva, passando l'elemento DOM, tutti gli attributi, l'attuale $ scope (che è un archivio di variabili locali) e alcuni altri bit utili. Questi attributi possono contenere espressioni che possono essere interpretate dalla direttiva e che indicano come renderizzarle e quando devono essere ridisegnate.

Le direttive possono quindi inserire componenti angolari aggiuntivi come controller, servizi, ecc. Ciò che emerge dal fondo del compilatore è un'applicazione Web completamente formata, cablata e pronta all'uso.

Ciò significa che Angular è Template Driven . Il tuo modello guida JavaScript, non viceversa. Si tratta di un'inversione radicale dei ruoli, e l'esatto contrario del discreto JavaScript che abbiamo scritto negli ultimi 10 anni circa. Questo può richiedere un po 'di tempo per abituarsi.

Se questo suona come potrebbe essere troppo prescrittivo e limitante, nulla potrebbe essere più lontano dalla verità. Poiché AngularJS tratta il codice HTML come codice, si ottiene una granularità a livello di HTML nell'applicazione Web . Tutto è possibile e la maggior parte delle cose è sorprendentemente facile quando fai qualche salto concettuale.

Passiamo al nocciolo della noia.

Innanzitutto, Angular non sostituisce jQuery

Angular e jQuery fanno cose diverse. AngularJS ti offre una serie di strumenti per produrre applicazioni web. jQuery offre principalmente strumenti per modificare il DOM. Se jQuery è presente sulla tua pagina, AngularJS la utilizzerà automaticamente. In caso contrario, AngularJS viene fornito con jQuery Lite, che è una versione ridotta, ma comunque perfettamente utilizzabile di jQuery.

A Misko piace jQuery e non si oppone al tuo utilizzo. Tuttavia, man mano che avanzi scoprirai che puoi svolgere praticamente tutto il tuo lavoro utilizzando una combinazione di ambito, modelli e direttive e dovresti preferire questo flusso di lavoro ove possibile perché il tuo codice sarà più discreto, più configurabile e altro Angolare.

Se usi jQuery, non dovresti spargerlo ovunque. Il posto corretto per la manipolazione del DOM in AngularJS è in una direttiva. Più su questi più tardi.

JavaScript discreto con selettori e modelli dichiarativi

jQuery viene generalmente applicato in modo discreto. Il tuo codice JavaScript è collegato nell'intestazione (o nel piè di pagina) e questo è l'unico posto in cui è menzionato. Usiamo i selettori per selezionare i bit della pagina e scrivere plugin per modificare quelle parti.

JavaScript ha il controllo. L'HTML ha un'esistenza completamente indipendente. Il tuo HTML rimane semantico anche senza JavaScript. Gli attributi di Onclick sono una pessima pratica.

Una delle prime cose che noterai su AngularJS è che gli attributi personalizzati sono ovunque . Il tuo HTML sarà disseminato di attributi ng, che sono essenzialmente attributi onClick sugli steroidi. Queste sono direttive (direttive del compilatore) e sono uno dei modi principali in cui il modello è agganciato al modello.

Quando lo vedi per la prima volta potresti essere tentato di scrivere AngularJS come JavaScript invadente della vecchia scuola (come ho fatto all'inizio). In effetti, AngularJS non gioca secondo queste regole. In AngularJS, HTML5 è un modello. È stato compilato da AngularJS per produrre la tua pagina web.

Questa è la prima grande differenza. Per jQuery, la tua pagina web è un DOM da manipolare. Per AngularJS, il tuo HTML è il codice da compilare. AngularJS legge in tutta la tua pagina web e la compila letteralmente in una nuova pagina web usando il suo compilatore incorporato.

Il modello dovrebbe essere dichiarativo; il suo significato dovrebbe essere chiaro semplicemente leggendolo. Utilizziamo attributi personalizzati con nomi significativi. Compiliamo nuovi elementi HTML, sempre con nomi significativi. Un designer con una conoscenza HTML minima e nessuna abilità di codifica può leggere il tuo modello AngularJS e capire cosa sta facendo. Lui o lei può apportare modifiche. Questa è la via angolare.

Il modello è al posto di guida.

Una delle prime domande che mi sono posto all'avvio di AngularJS e durante l'esecuzione dei tutorial è "Dov'è il mio codice?" . Non ho scritto JavaScript, eppure ho tutto questo comportamento. La risposta è ovvia Poiché AngularJS compila il DOM, AngularJS tratta il tuo HTML come codice. Per molti casi semplici è spesso sufficiente scrivere un modello e lasciare che AngularJS lo compili in un'applicazione per te.

Il tuo modello guida la tua applicazione. È trattato come un DSL . Scrivi i componenti di AngularJS e AngularJS si occuperà di inserirli e renderli disponibili al momento giusto in base alla struttura del modello. Questo è molto diverso da un modello MVC standard , in cui il modello è solo per l'output.

È più simile a XSLT che ad esempio Ruby on Rails .

Questa è una radicale inversione di controllo che richiede un po 'di tempo per abituarsi.

Smetti di provare a guidare la tua applicazione dal tuo JavaScript. Lascia che il modello guidi l'applicazione e che AngularJS si occupi del cablaggio dei componenti. Anche questa è la via angolare.

HTML semantico vs. modelli semantici

Con jQuery la tua pagina HTML dovrebbe contenere contenuti semantici significativi. Se JavaScript è disattivato (da un utente o motore di ricerca) i tuoi contenuti restano accessibili.

Perché AngularJS tratta la tua pagina HTML come modello. Il modello non dovrebbe essere semantico in quanto il contenuto è in genere archiviato nel modello che alla fine proviene dall'API. AngularJS compila il tuo DOM con il modello per produrre una pagina web semantica.

La tua sorgente HTML non è più semantica, invece, la tua API e il DOM compilato sono semantici.

In AngularJS, che significa vita nel modello, l'HTML è solo un modello, solo per la visualizzazione.

A questo punto probabilmente hai ogni sorta di domande riguardanti SEO e accessibilità, e giustamente. Ci sono problemi aperti qui. La maggior parte degli screen reader ora analizzerà JavaScript. I motori di ricerca possono anche indicizzare i contenuti AJAX . Tuttavia, vorrai assicurarti di utilizzare URL pushstate e di avere una sitemap decente. Vedi qui per una discussione del problema: https://stackoverflow.com/a/23245379/687677

Separazione delle preoccupazioni (SOC) vs. MVC

La separazione delle preoccupazioni (SOC) è un modello che è cresciuto in molti anni di sviluppo web per una serie di ragioni tra cui SEO, accessibilità e incompatibilità del browser. Sembra così:

  1. HTML - Significato semantico. L'HTML dovrebbe essere autonomo.
  2. CSS - Styling, senza CSS la pagina è ancora leggibile.
  3. JavaScript - Comportamento, senza lo script il contenuto rimane.

Ancora una volta, AngularJS non gioca secondo le loro regole. In un colpo solo, AngularJS elimina un decennio di saggezza ricevuta e invece implementa un modello MVC in cui il modello non è più semantico, nemmeno un po '.

Sembra così:

  1. Modello: i tuoi modelli contengono i tuoi dati semantici. I modelli sono generalmente oggetti JSON . I modelli esistono come attributi di un oggetto chiamato $ scope. Puoi anche memorizzare pratiche funzioni di utilità su $ scope a cui i tuoi modelli possono quindi accedere.
  2. Visualizza: le tue visualizzazioni sono scritte in HTML. La vista di solito non è semantica perché i tuoi dati risiedono nel modello.
  3. Controller: il controller è una funzione JavaScript che aggancia la vista al modello. La sua funzione è di inizializzare $ scope. A seconda dell'applicazione, potrebbe essere necessario o meno creare un controller. Puoi avere molti controller in una pagina.

MVC e SOC non si trovano su estremità opposte della stessa scala, ma su assi completamente diversi. SOC non ha senso in un contesto AngularJS. Devi dimenticarlo e andare avanti.

Se, come me, hai vissuto le guerre del browser, potresti trovare questa idea abbastanza offensiva. Superalo, ne varrà la pena, lo prometto.

Plugin vs. Direttive

I plugin estendono jQuery. Le direttive AngularJS estendono le funzionalità del tuo browser.

In jQuery definiamo i plugin aggiungendo funzioni a jQuery.prototype. Quindi li colleghiamo al DOM selezionando gli elementi e chiamando il plugin sul risultato. L'idea è di estendere le capacità di jQuery.

Ad esempio, se vuoi una giostra sulla tua pagina, potresti definire un elenco non ordinato di figure, magari avvolto in un elemento nav. È quindi possibile scrivere un po 'di jQuery per selezionare l'elenco sulla pagina e ripristinarlo come una galleria con timeout per eseguire l'animazione scorrevole.

In AngularJS, definiamo le direttive. Una direttiva è una funzione che restituisce un oggetto JSON. Questo oggetto indica ad AngularJS quali elementi DOM cercare e quali modifiche apportare ad essi. Le direttive sono agganciate al modello usando attributi o elementi, che inventi. L'idea è di estendere le capacità di HTML con nuovi attributi ed elementi.

Il modo AngularJS è quello di estendere le capacità dell'HTML nativo. Dovresti scrivere HTML che assomigli a HTML, esteso con attributi ed elementi personalizzati.

Se vuoi una giostra, usa semplicemente un <carousel />elemento, quindi definisci una direttiva per inserire un modello e far funzionare quella ventosa.

Molte piccole direttive contro grandi plugin con switch di configurazione

La tendenza con jQuery è quella di scrivere grandi plugin di grandi dimensioni come lightbox che poi configuriamo passando in numerosi valori e opzioni.

Questo è un errore in AngularJS.

Prendi l'esempio di un menu a discesa. Quando si scrive un plug-in a discesa, si potrebbe essere tentati di codificare nei gestori dei clic, forse una funzione da aggiungere in un chevron che è su o giù, forse cambiare la classe dell'elemento spiegato, mostrare nascondere il menu, tutto ciò che è utile.

Fino a quando non si desidera apportare una piccola modifica.

Supponi di avere un menu che desideri aprire al passaggio del mouse. Bene, ora abbiamo un problema. Il nostro plugin ha collegato il nostro gestore di clic per noi, avremo bisogno di aggiungere un'opzione di configurazione per farlo funzionare diversamente in questo caso specifico.

In AngularJS scriviamo direttive più piccole. La nostra direttiva a discesa sarebbe ridicolmente piccola. Potrebbe mantenere lo stato piegato e fornire metodi per fold (), unfold () o toggle (). Questi metodi aggiornerebbero semplicemente $ scope.menu.visible che è un valore booleano che detiene lo stato.

Ora nel nostro modello possiamo collegarlo:

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

Devi aggiornare al passaggio del mouse?

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

Il modello guida l'applicazione in modo da ottenere una granularità di livello HTML. Se vogliamo fare eccezioni caso per caso, il modello lo rende facile.

Chiusura vs. $ scope

I plugin JQuery vengono creati in una chiusura. La privacy è mantenuta all'interno di quella chiusura. Sta a te mantenere la catena di portata all'interno di quella chiusura. Hai davvero accesso solo al set di nodi DOM passati al plugin da jQuery, oltre a tutte le variabili locali definite nella chiusura e tutti i globi che hai definito. Ciò significa che i plugin sono abbastanza autonomi. Questa è una buona cosa, ma può diventare restrittiva quando si crea un'intera applicazione. Cercare di passare i dati tra le sezioni di una pagina dinamica diventa un lavoro ingrato.

AngularJS ha oggetti $ scope. Questi sono oggetti speciali creati e gestiti da AngularJS in cui memorizzi il tuo modello. Alcune direttive genereranno un nuovo $ scope, che per impostazione predefinita eredita dal suo $ scope avvolgente usando l'ereditarietà prototipica di JavaScript. L'oggetto $ scope è accessibile nel controller e nella vista.

Questa è la parte intelligente. Poiché la struttura dell'ereditarietà di $ scope segue approssimativamente la struttura del DOM, gli elementi hanno accesso al proprio ambito e a tutti gli ambiti contenenti senza soluzione di continuità, fino all'ambito $ scope globale (che non è lo stesso dell'ambito globale).

Ciò semplifica notevolmente il trasferimento dei dati e l'archiviazione dei dati a un livello appropriato. Se un menu a discesa è spiegato, solo il menu a discesa $ scope deve saperlo. Se l'utente aggiorna le sue preferenze, potresti voler aggiornare l'ambito $ $ globale e tutti gli ambiti nidificati che ascoltano le preferenze dell'utente verrebbero automaticamente avvisati.

Potrebbe sembrare complicato, infatti, una volta che ti rilassi, è come volare. Non è necessario creare l'oggetto $ scope, AngularJS crea un'istanza e la configura per te, in modo corretto e appropriato in base alla gerarchia dei modelli. AngularJS lo rende quindi disponibile per il tuo componente usando la magia dell'iniezione di dipendenza (ne parleremo più avanti).

Modifiche DOM manuali rispetto a Data Binding

In jQuery apporti manualmente tutte le modifiche al DOM. Costruisci nuovi elementi DOM a livello di codice. Se si dispone di un array JSON e si desidera inserirlo nel DOM, è necessario scrivere una funzione per generare l'HTML e inserirlo.

In AngularJS puoi farlo anche tu, ma sei incoraggiato a ricorrere all'associazione dei dati. Cambia il tuo modello e poiché il DOM è associato ad esso tramite un modello che il DOM si aggiornerà automaticamente, non è necessario alcun intervento.

Poiché l'associazione dei dati viene eseguita dal modello, utilizzando un attributo o la sintassi del parentesi graffa, è semplicissimo da eseguire. C'è un piccolo sovraccarico cognitivo ad esso associato, quindi ti ritroverai a farlo sempre.

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

Associa l'elemento di input a $scope.user.name. L'aggiornamento dell'input aggiornerà il valore nell'ambito corrente e viceversa.

Allo stesso modo:

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

produrrà il nome utente in un paragrafo. È un'associazione live, quindi se il $scope.user.namevalore viene aggiornato, verrà aggiornato anche il modello.

Ajax tutto il tempo

In jQuery effettuare una chiamata Ajax è abbastanza semplice, ma è ancora qualcosa a cui potresti pensare due volte. C'è una maggiore complessità a cui pensare e una buona dose di sceneggiatura da mantenere.

In AngularJS, Ajax è la tua soluzione predefinita e succede sempre, quasi senza che te ne accorga. Puoi includere modelli con ng-include. È possibile applicare un modello con la direttiva personalizzata più semplice. Puoi concludere una chiamata Ajax in un servizio e crearti un servizio GitHub o un servizio Flickr , a cui puoi accedere con una facilità sorprendente.

Oggetti di servizio e funzioni di supporto

In jQuery, se vogliamo svolgere una piccola attività non dom-dom come estrarre un feed da un'API, potremmo scrivere una piccola funzione per farlo nella nostra chiusura. Questa è una soluzione valida, ma cosa succede se vogliamo accedere a quel feed spesso? Cosa succede se vogliamo riutilizzare quel codice in un'altra applicazione?

AngularJS ci fornisce oggetti di servizio.

I servizi sono oggetti semplici che contengono funzioni e dati. Sono sempre dei singoli, il che significa che non può mai essercene più di uno. Supponiamo di voler accedere all'API Stack Overflow, potremmo scrivere un StackOverflowServicemetodo che definisce i metodi per farlo.

Diciamo che abbiamo un carrello. Potremmo definire un ShoppingCartService che mantiene il nostro carrello e contiene metodi per aggiungere e rimuovere articoli. Poiché il servizio è un singleton ed è condiviso da tutti gli altri componenti, qualsiasi oggetto che è necessario può scrivere nel carrello e estrarre i dati da esso. È sempre lo stesso carrello.

Gli oggetti di servizio sono componenti AngularJS indipendenti che possiamo usare e riutilizzare a nostro piacimento. Sono semplici oggetti JSON contenenti funzioni e dati. Sono sempre singoli, quindi se si memorizzano i dati su un servizio in un posto, è possibile ottenere quei dati altrove semplicemente richiedendo lo stesso servizio.

Iniezione di dipendenza (DI) vs. Instatiation - alias de-spaghettification

AngularJS gestisce le tue dipendenze per te. Se vuoi un oggetto, fai semplicemente riferimento ad esso e AngularJS lo otterrà per te.

Fino a quando non inizierai a usarlo, è difficile spiegare che enorme vantaggio sia questo. Niente come AngularJS DI esiste all'interno di jQuery.

DI significa che invece di scrivere l'applicazione e collegarla insieme, si definisce invece una libreria di componenti, ognuno identificato da una stringa.

Supponiamo di avere un componente chiamato "FlickrService" che definisce i metodi per estrarre i feed JSON da Flickr. Ora, se voglio scrivere un controller in grado di accedere a Flickr, devo solo fare riferimento al 'FlickrService' per nome quando dichiaro il controller. AngularJS si occuperà di creare un'istanza del componente e renderlo disponibile al mio controller.

Ad esempio, qui definisco un servizio:

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

Ora, quando voglio usare quel servizio, mi riferisco ad esso semplicemente come questo:

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

AngularJS riconoscerà che è necessario un oggetto FlickrService per creare un'istanza del controller e ce ne fornirà uno per noi.

Questo rende il cablaggio molto semplice e praticamente elimina qualsiasi tendenza alla spagettificazione. Abbiamo un elenco semplice di componenti e AngularJS ce li consegna uno per uno come e quando ne abbiamo bisogno.

Architettura di servizio modulare

jQuery dice molto poco su come dovresti organizzare il tuo codice. AngularJS ha opinioni.

AngularJS ti offre moduli in cui puoi inserire il tuo codice. Se stai scrivendo uno script che parla con Flickr, ad esempio, potresti voler creare un modulo Flickr per avvolgere tutte le tue funzioni relative a Flickr. I moduli possono includere altri moduli (DI). La tua applicazione principale di solito è un modulo e questo dovrebbe includere tutti gli altri moduli da cui dipenderà la tua applicazione.

Ottieni un semplice riutilizzo del codice, se vuoi scrivere un'altra applicazione basata su Flickr, puoi semplicemente includere il modulo Flickr e voilà, hai accesso a tutte le tue funzioni relative a Flickr nella tua nuova applicazione.

I moduli contengono componenti AngularJS. Quando includiamo un modulo, tutti i componenti in quel modulo diventano disponibili per noi come un semplice elenco identificato dalle loro stringhe uniche . Possiamo quindi iniettare quei componenti l'uno nell'altro usando il meccanismo di iniezione di dipendenza di AngularJS.

Per riassumere

AngularJS e jQuery non sono nemici. È possibile utilizzare jQuery in AngularJS molto bene. Se stai usando bene AngularJS (template, data binding, $ scope, direttive, ecc.) Scoprirai che hai bisogno di molto meno jQuery di quanto potresti altrimenti richiedere.

La cosa principale da capire è che il tuo modello guida la tua applicazione. Smetti di provare a scrivere grandi plugin che fanno tutto. Invece scrivi piccole direttive che fanno una cosa, quindi scrivi un semplice modello per collegarle.

Pensa meno a JavaScript discreto e pensa invece in termini di estensioni HTML.

Il mio piccolo libro

Ero così eccitato per AngularJS, ho scritto un breve libro su di esso che sei il benvenuto a leggere online http://nicholasjohnson.com/angular-book/ . Spero sia utile


6
L'idea che "Separation of Concerns" sia diversa da "MVC (Model, View, Controller)" è completamente falsa. Il modello dei linguaggi Web di separazione delle preoccupazioni (HTML, CSS e JS) lo fa consentendo alle persone di inserire elementi in una pagina Web (markup / HTML) senza preoccuparsi di come appare (stile / layout / CSS) o cosa "fa" (Eventi DOM / AJAX / JavaScript). MVC separa anche le preoccupazioni. Ogni "livello" nel modello MVC ha un ruolo distinto: dati, routing / logica o rendering. I livelli sono accoppiati da callback, route e associazioni di modelli. In teoria, una persona può specializzarsi in ogni livello, come spesso accade.

Come qualcuno che proviene da un rigoroso background SOC e come difensore di lunga data degli standard web risalenti alle guerre del browser, inizialmente ho trovato fastidiosi i modelli non semantici e non validanti di Angular. Volevo solo chiarire che per scrivere Angular è necessario lasciar andare il SOC come è generalmente praticato. Questa può essere una transizione difficile.
superluminario,

Hai ragione. SOC è un termine generico, ma nel mondo web SOC ha (o forse ha avuto) un significato molto specifico: HTML semantico, CSS di presentazione e JavaScript per il comportamento. Sto facendo alcune ipotesi sul mio pubblico che forse non sono ragionevoli, quindi dovrei scusarmi anche.
superluminario

Trovo la tua risposta più chiara e illuminante. Sono un principiante qui, quindi, se ho un'estensione per cambiare una pagina esistente (che non controllo), dovrei tenere JQuery allora?
Daniel Möller,

152

Puoi descrivere il cambio di paradigma necessario?

Imperativo vs Dichiarativo

Con jQuery dici al DOM cosa deve succedere, passo dopo passo. Con AngularJS descrivi quali risultati vuoi ma non come farlo. Maggiori informazioni qui . Inoltre, controlla la risposta di Mark Rajcok.

Come posso progettare e progettare app Web sul lato client in modo diverso?

AngularJS è un intero framework lato client che utilizza il modello MVC (controlla la loro rappresentazione grafica ). Si concentra fortemente sulla separazione delle preoccupazioni.

Qual è la differenza più grande? Cosa dovrei smettere di fare / usare; cosa dovrei iniziare a fare / usare invece?

jQuery è una libreria

AngularJS è un bellissimo framework lato client, altamente testabile, che combina tonnellate di cose interessanti come MVC, iniezione di dipendenza , associazione di dati e molto altro.

Si concentra sulla separazione delle preoccupazioni e dei test (test unitari e test end-to-end), che facilita lo sviluppo guidato dai test.

Il modo migliore per iniziare è passare attraverso il loro fantastico tutorial . Puoi seguire i passaggi in un paio d'ore; tuttavia, nel caso tu voglia padroneggiare i concetti dietro le quinte, includono una miriade di riferimenti per ulteriori letture.

Ci sono considerazioni / restrizioni sul lato server?

È possibile utilizzarlo su applicazioni esistenti in cui si sta già utilizzando jQuery puro. Tuttavia, se si desidera sfruttare appieno le funzionalità di AngularJS, è possibile valutare la possibilità di codificare il lato server utilizzando un approccio RESTful .

Ciò ti consentirà di sfruttare la loro fabbrica di risorse , che crea un'astrazione dell'API RESTful sul lato server e rende le chiamate sul lato server (ottieni, salva, elimina, ecc.) Incredibilmente facili.


27
Penso che tu stia confondendo le acque parlando di come jQuery sia una "libreria" e Angular sia un "framework" ... per prima cosa, penso che sia possibile sostenere che jQuery sia un framework ... è un'astrazione di manipolazione DOM e gestione degli eventi. Potrebbe non essere un framework per lo stesso tipo di cose di Angular, ma questo è il dilemma in cui si trova chi pone le domande: non conoscono davvero la differenza tra Angular e jQuery, e per quanto lo sappia, jQuery è un framework per la creazione di siti Web pesanti per i clienti. Quindi discutere sulla terminologia non chiarirà le cose.
Zando,

15
Penso che tu sia quello che si sta confondendo. Questa domanda si rivolge esattamente a questo stackoverflow.com/questions/7062775 . Inoltre, questa risposta può aiutare a chiarire qual è la differenza tra un framework e una libreria: stackoverflow.com/a/148759/620448
Ulises

6
Una libreria non diventa un "framework" solo perché la sua raccolta di funzioni è particolarmente utile o di grandi dimensioni. Un framework prende decisioni per te. Quando inizi a utilizzare AngularJS, è probabile che ti accoppi ad esso per sua natura. (Es .: dovresti aggiornare il DOM solo nelle direttive, altrimenti qualcosa non funzionerà.) Questo perché AngularJS è un framework. Quando si utilizza jQuery, è possibile combinare gli strumenti in modo relativamente semplice con il minimo rischio di conflitto. Questo perché jQuery è una libreria e almeno una metà decente.

8
Una libreria è il codice che chiami. Un framework è un codice che chiama il tuo codice. Con questa definizione Angular è un framework. Lo fornite con componenti e Angular fa in modo che i vostri componenti siano istanziati con le dipendenze di cui hanno bisogno.
superluminario,

84

Per descrivere il "cambio di paradigma", penso che una breve risposta possa essere sufficiente.

AngularJS cambia il modo in cui trovi gli elementi

In jQuery , in genere si utilizzano i selettori per trovare gli elementi, quindi collegarli:
$('#id .class').click(doStuff);

In AngularJS , usi le direttive per contrassegnare direttamente gli elementi, per collegarli:
<a ng-click="doStuff()">

AngularJS non ha bisogno (o desidera) di trovare elementi utilizzando i selettori: la differenza principale tra jqLite di AngularJS e jQuery in piena regola è che jqLite non supporta i selettori .

Quindi quando le persone dicono "non includere affatto jQuery", è principalmente perché non vogliono che tu usi i selettori; vogliono invece che tu impari a usare le direttive. Diretto, non selezionare!


13
Proprio come una dichiarazione di non responsabilità, ci sono MOLTE più grandi differenze tra Angular e jQuery. Ma trovare elementi è quello che richiede il più grande cambiamento di pensiero.
Scott Rippey,

1
perdonami se sbaglio, ma pensavo che un selettore fosse quello che usi per trovare l'elemento DOM? Preferisci mantenere ogni singola parte dell'interfaccia utente appena caricata in riferimento, piuttosto che selezionare semplicemente uno o 2 elementi su cui un utente può fare clic, al volo usando un selettore? sembra più difficile per me ..
RozzA

3
@AlexanderPritchard Il punto di Angular è che non selezioni dal tuo JavaScript, ma direttamente dal tuo modello. È un'inversione di controllo che mette il potere nelle mani del designer. Questo è un principio progettuale deliberato. Per ottenere veramente Angular devi pensare al tuo codice in questo modo. È un duro cambiamento da fare.
superluminario,

3
@superluminary Che bella citazione! "non selezionare; diretto!" Seriamente, lo userò.
Scott Rippey,

1
Questa è una delle mie cose preferite di AngularJS. Non devo preoccuparmi che il team UX abbia rotto la mia funzionalità o che io abbia rotto i loro stili. Usano le lezioni, io uso le direttive, punto. Non mi manca un po 'di selettori.
adam0101,

69

jQuery

jQuery crea comandi JavaScript ridicolmente lunghi come getElementByHerpDerppiù brevi e cross-browser.

AngularJS

AngularJS ti permette di creare i tuoi tag / attributi HTML che fanno cose che funzionano bene con le applicazioni web dinamiche (poiché l'HTML è stato progettato per le pagine statiche).

Modificare:

Dicendo "Ho un background jQuery come penso in AngularJS?" è come dire "Ho un background HTML come penso in JavaScript?" Il fatto che tu stia ponendo la domanda dimostra che molto probabilmente non capisci gli scopi fondamentali di queste due risorse. Questo è il motivo per cui ho scelto di rispondere alla domanda semplicemente sottolineando la differenza fondamentale piuttosto che passare attraverso l'elenco dicendo "AngularJS fa uso di direttive mentre jQuery usa i selettori CSS per creare un oggetto jQuery che fa questo e quello ecc ...." . Questa domanda non richiede una risposta lunga.

jQuery è un modo per semplificare la programmazione di JavaScript nel browser. Comandi più brevi tra browser, ecc.

AngularJS estende l'HTML, quindi non devi inserirti ovunque <div>per fare un'applicazione. Rende l'HTML effettivamente funzionante per le applicazioni piuttosto che per quello per cui è stato progettato, ovvero pagine Web statiche ed educative. Lo fa in modo circolare usando JavaScript, ma fondamentalmente è un'estensione di HTML, non JavaScript.


@Robert dipende da cosa stai facendo. $(".myclass")è estremamente comune e più che un po 'più semplice in jQuery rispetto a PO-Javascript.
Rob Grant,

61

jQuery: pensi molto a "QUERYing DOM " per gli elementi DOM e fare qualcosa.

AngularJS: IL modello è la verità e pensi sempre da quell'ANGOLO.

Ad esempio, quando si ottengono dati dal server che si intende visualizzare in un formato nel DOM, in jQuery, è necessario '1. TROVA dove nel DOM vuoi inserire questi dati, il '2. AGGIORNA / APPENDI 'lì creando un nuovo nodo o semplicemente impostando il suo HTML interno . Quindi, quando si desidera aggiornare questa vista, è quindi '3. TROVA 'la posizione e' 4. AGGIORNARE'. Questo ciclo di ricerca e aggiornamento eseguito nello stesso contesto di acquisizione e formattazione dei dati dal server è scomparso in AngularJS.

Con AngularJS hai il tuo modello (oggetti JavaScript a cui sei già abituato) e il valore del modello ti dice del modello (ovviamente) e della vista, e un'operazione sul modello si propaga automaticamente alla vista, quindi non non ci devo pensare. Ti ritroverai in AngularJS che non trovi più cose nel DOM.

In altre parole, in jQuery, devi pensare ai selettori CSS, ovvero dove si trova divo tdche ha una classe o un attributo, ecc., In modo che io possa ottenere il loro HTML o colore o valore, ma in AngularJS, ti ritroverai a pensare in questo modo: con quale modello ho a che fare, imposterò il valore del modello su vero. Non ti stai preoccupando se la vista che riflette questo valore è una casella selezionata o risiede in un tdelemento (dettagli che avresti spesso bisogno di pensare in jQuery).

E con la manipolazione del DOM in AngularJS, ti ritrovi ad aggiungere direttive e filtri, a cui puoi pensare come estensioni HTML valide.

Un'altra cosa che sperimenterai in AngularJS: in jQuery chiami molto le funzioni jQuery, in AngularJS, AngularJS chiamerà le tue funzioni, quindi AngularJS ti dirà come fare le cose, ma i vantaggi ne valgono la pena, quindi imparando AngularJS di solito significa imparare ciò che AngularJS vuole o il modo in cui AngularJS richiede che tu presenti le tue funzioni e le chiamerà di conseguenza. Questa è una delle cose che rende AngularJS un framework piuttosto che una libreria.


46

Queste sono alcune risposte molto belle, ma lunghe.

Per riassumere le mie esperienze:

  1. I controller e i fornitori (servizi, fabbriche, ecc.) Servono per modificare il modello di dati, NON HTML.
  2. HTML e direttive definiscono il layout e l'associazione al modello.
  3. Se è necessario condividere i dati tra i controller, creare un servizio o una fabbrica: si tratta di singoli elementi condivisi nell'applicazione.
  4. Se hai bisogno di un widget HTML, crea una direttiva.
  5. Se disponi di alcuni dati e stai provando ad aggiornare HTML ... STOP! aggiorna il modello e assicurati che il codice HTML sia associato al modello.

45

jQuery è una libreria di manipolazione DOM.

AngularJS è un framework MV *.

Infatti, AngularJS è uno dei pochi framework JavaScript MV * (molti strumenti JavaScript MVC rientrano ancora nella libreria delle categorie).

Essendo un framework, ospita il tuo codice e prende la proprietà delle decisioni su cosa chiamare e quando!

AngularJS stesso include al suo interno un'edizione jQuery-lite. Pertanto, per alcune selezioni / manipolazioni DOM di base, non è necessario includere la libreria jQuery (consente di risparmiare molti byte per l'esecuzione sulla rete).

AngularJS ha il concetto di "Direttive" per la manipolazione del DOM e la progettazione di componenti UI riutilizzabili, quindi dovresti usarlo ogni volta che senti la necessità di fare cose relative alla manipolazione del DOM (le direttive sono solo il luogo dove dovresti scrivere il codice jQuery mentre usi AngularJS).

AngularJS prevede alcune curve di apprendimento (più di jQuery :-).

-> Per qualsiasi sviluppatore proveniente da background jQuery, il mio primo consiglio sarebbe di "imparare JavaScript come linguaggio di prima classe prima di passare a un framework ricco come AngularJS!" Ho imparato il fatto sopra nel modo più duro.

In bocca al lupo.


34

Sono mele e arance. Non vuoi confrontarli. Sono due cose diverse. AngularJs ha già incorporato jQuery che consente di eseguire la manipolazione DOM di base senza nemmeno includere la versione jQuery completa.

jQuery è tutto sulla manipolazione del DOM. Risolve tutto il dolore del cross browser altrimenti dovrai affrontare, ma non è un framework che ti consente di dividere la tua app in componenti come AngularJS.

Una cosa bella di AngularJs è che ti permette di separare / isolare la manipolazione del DOM nelle direttive. Ci sono direttive integrate pronte per l'uso come ng-click. Puoi creare le tue direttive personalizzate che conterranno tutta la tua logica di visualizzazione o manipolazione DOM in modo da non confondere il codice di manipolazione DOM nei controller o nei servizi che dovrebbero occuparsi della logica aziendale.

Angolare suddivide la tua app in - Controller - Servizi - Viste - ecc.

e c'è un'altra cosa, questa è la direttiva. È un attributo che puoi collegare a qualsiasi elemento DOM e puoi impazzire con jQuery al suo interno senza preoccuparti che jQuery sia mai in conflitto con i componenti di AngularJs o rovini con la sua architettura.

Ho sentito da un incontro a cui ho partecipato, uno dei fondatori di Angular ha detto che hanno lavorato duramente per separare la manipolazione del DOM, quindi non provare a includerli di nuovo.


31

Ascolta il podcast JavaScript Jabber: Episode # 32 che presenta i creatori originali di AngularJS: Misko Hevery e Igor Minar. Parlano molto di com'è arrivare ad AngularJS da altri sfondi JavaScript, in particolare jQuery.

Uno dei punti evidenziati nel podcast ha fatto molte cose fare clic per me per quanto riguarda la tua domanda:

MISKO : [...] una delle cose a cui pensavamo molto poco in Angular è, come possiamo fornire un sacco di tratte di fuga in modo da poter uscire e fondamentalmente trovare una soluzione. Quindi per noi la risposta è questa cosa chiamata "Direttive". E con le direttive, diventi essenzialmente un normale jQuery JavaScript, puoi fare quello che vuoi.

IGOR : Quindi pensa alla direttiva come all'istruzione per il compilatore che lo dice ogni volta che incontri questo certo elemento o questo CSS nel modello, e mantieni questo tipo di codice e quel codice è responsabile dell'elemento e di tutto sotto quell'elemento nella struttura del DOM.

Una trascrizione dell'intero episodio è disponibile al link fornito sopra.

Quindi, per rispondere direttamente alla tua domanda: AngularJS è molto supponente ed è un vero framework MV *. Tuttavia, puoi comunque fare tutte le cose davvero interessanti che conosci e ami con jQuery all'interno delle direttive. Non è una questione di "Come posso fare quello che ero solito in jQuery?" tanto quanto è una questione di "Come posso integrare AngularJS con tutte le cose che facevo in jQuery?"

Sono davvero due stati d'animo molto diversi.


2
Non sono sicuro che sarei abbastanza d'accordo che Angular sia MOLTO supponente. Vuoi essere supponente, guarda Ember. Descriverei Angular come se avesse opinioni da goldilocks - per quello che vedo, jQuery ha troppe opinioni ed Ember ha troppe. Angular sembra giusto.
fool4jesus,

30

Trovo questa domanda interessante, perché la mia prima seria esposizione alla programmazione JavaScript è stata Node.js e AngularJS. Non ho mai imparato jQuery e immagino sia una buona cosa, perché non devo disimparare nulla. In effetti, evito attivamente le soluzioni jQuery ai miei problemi e, invece, cerco solo un "modo AngularJS" per risolverli. Quindi, immagino che la mia risposta a questa domanda si ridurrebbe essenzialmente a "pensare come qualcuno che non ha mai imparato jQuery" ed evitare qualsiasi tentazione di incorporare direttamente jQuery (ovviamente AngularJS lo usa in qualche misura dietro le quinte).


23

AngularJS e jQuery:

AngularJs e JQuery sono completamente diversi a tutti i livelli tranne la funzionalità JQLite e lo vedrai una volta che inizierai ad apprendere le funzionalità principali di AngularJs (l'ho spiegato di seguito).

AngularJs è un framework lato client che offre di creare l'applicazione lato client indipendente. JQuery è una libreria lato client che gioca attorno al DOM.

Principio interessante di AngularJs: se desideri alcune modifiche all'interfaccia utente, pensa dal punto di vista della modifica dei dati del modello. Modifica i tuoi dati e l'interfaccia utente verrà nuovamente renderizzata. Non è necessario giocare a DOM ogni volta, a meno che e fino a quando non è quasi necessario e che dovrebbe essere gestito anche attraverso le Direttive angolari.

Per rispondere a questa domanda, voglio condividere la mia esperienza sulla prima applicazione aziendale con AngularJS. Queste sono le caratteristiche più straordinarie che Angular offre quando iniziamo a cambiare la nostra mentalità jQuery e otteniamo l'Angular come un framework e non la libreria.

L'associazione dati bidirezionale è sorprendente: avevo una griglia con tutte le funzionalità UPDATE, DELTE, INSERT. Ho un oggetto dati che lega il modello della griglia usando ng-repeat. Hai solo bisogno di scrivere una sola riga di semplice codice JavaScript per eliminare e inserire e basta. grid si aggiorna automaticamente quando il modello di griglia cambia istantaneamente. La funzionalità di aggiornamento è in tempo reale, nessun codice per questo. Ti senti fantastico !!!

Le direttive riutilizzabili sono super: scrivi le direttive in un unico posto e usale in tutta l'applicazione. OH MIO DIO!!! Ho usato queste direttive per cercapersone, regex, validazioni, ecc. È davvero fantastico!

Il routing è forte: dipende dalla tua implementazione come vuoi usarlo, ma richiede pochissime righe di codice per instradare la richiesta per specificare HTML e controller (JavaScript)

I controller sono fantastici: i controller si prendono cura del proprio HTML, ma questa separazione funziona bene anche per funzionalità comuni. Se si desidera chiamare la stessa funzione facendo clic su un pulsante sull'HTML master, scrivere lo stesso nome di funzione in ciascun controller e scrivere il codice individuale.

Plugin: ci sono molte altre funzionalità simili come mostrare un overlay nella tua app. Non è necessario scrivere codice per questo, basta usare un plug-in overlay disponibile come wc-overlay e questo si occuperà automaticamente di tutte le richieste XMLHttpRequest (XHR).

Ideale per l' architettura RESTful : essere un framework completo rende AngularJS eccezionale per lavorare con un'architettura RESTful. Chiamare le API REST CRUD è molto più semplice e

Servizi : scrivere codici comuni utilizzando i servizi e meno codice nei controller. I servizi possono essere utilizzati per condividere funzionalità comuni tra i controller.

Estensibilità : Angular ha esteso le direttive HTML usando direttive angolari. Scrivi espressioni all'interno di HTML e valutale in fase di esecuzione. Crea le tue direttive e i tuoi servizi e usali in un altro progetto senza alcuno sforzo aggiuntivo.


20

Come principiante di JavaScript MV * e focalizzato esclusivamente sull'architettura dell'applicazione (non sul lato server / lato client), consiglierei sicuramente la seguente risorsa (che mi sorprende non sia stata ancora menzionata): JavaScript Design Patterns , di Addy Osmani , come introduzione a diversi modelli di progettazione JavaScript . I termini utilizzati in questa risposta sono presi dal documento collegato sopra. Non ripeterò ciò che è stato scritto molto bene nella risposta accettata. Invece, questa risposta rimanda agli sfondi teorici che alimentano AngularJS (e altre librerie).

Come me, ti renderai presto conto che AngularJS (o Ember.js , Durandal e altri framework MV * del resto) è un framework complesso che riunisce molti dei diversi modelli di progettazione JavaScript.

Ho trovato anche più facile testare (1) codice JavaScript nativo e (2) librerie più piccole per ognuno di questi schemi separatamente prima di immergermi in un framework globale. Questo mi ha permesso di capire meglio quali questioni cruciali affronta un framework (perché tu sei personalmente di fronte al problema).

Per esempio:

  • Programmazione orientata agli oggetti JavaScript (questo è un link di ricerca di Google). Non è una libreria, ma sicuramente un prerequisito per qualsiasi programmazione dell'applicazione. Mi ha insegnato le implementazioni native dei modelli prototipo, costruttore, singleton e decoratore
  • jQuery / Underscore per il modello di facciata (come WYSIWYG per manipolare il DOM)
  • Prototype.js per il modello prototipo / costruttore / mixin
  • RequireJS / Curl.js per il modello di modulo / AMD
  • KnockoutJS per il modello osservabile, di pubblicazione / sottoscrizione

NB: questo elenco non è completo, né "le migliori librerie"; sono solo le librerie che ho usato. Queste librerie includono anche più modelli, quelli menzionati sono solo i loro obiettivi principali o intenti originali. Se ritieni che manchi qualcosa da questo elenco, per favore ricordalo nei commenti e sarò felice di aggiungerlo.


12

In realtà, se stai usando AngularJS, non hai più bisogno di jQuery. AngularJS stesso ha il legame e la direttiva, che è un'ottima "sostituzione" per la maggior parte delle cose che puoi fare con jQuery.

Di solito sviluppo applicazioni mobili usando AngularJS e Cordova . L'unica cosa di jQuery di cui avevo bisogno è il selettore.

Cercando su google, vedo che esiste un modulo selettore jQuery autonomo. È Sizzle.

E ho deciso di creare un piccolo frammento di codice che mi aiuti ad avviare rapidamente un sito Web usando AngularJS con la potenza di jQuery Selector (usando Sizzle).

Ho condiviso il mio codice qui: https://github.com/huytd/Sizzular

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.