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


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

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

Non sto cercando un confronto dettagliato tra jQuery e AngularJS.


4525
2018-02-21 04:09


origine


risposte:


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

In jQuery, si progetta una pagina e quindi la si rende dinamica. Questo perché jQuery è stato progettato per l'ampliamento ed è cresciuto incredibilmente da questa semplice premessa.

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

2. Non aumentare jQuery con AngularJS

Allo stesso modo, non iniziare con l'idea che jQuery fa X, Y e Z, quindi aggiungerò semplicemente AngularJS per modelli e controller. Questo è veramente  allettante quando sei appena agli inizi, motivo per cui consiglio sempre ai nuovi sviluppatori di AngularJS di non utilizzare jQuery, almeno fino a quando non si abituano a fare cose come "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 serie di callback e $applys che sono confusi e contorti; ma alla fine lo fanno funzionare! Il problema è che dentro maggior parte  casi in cui il plugin jQuery potrebbe essere riscritto in AngularJS in una frazione del codice, dove all'improvviso tutto diventa comprensibile e diretto.

La linea di fondo è questa: quando si risolve, prima "pensa in AngularJS"; se non riesci a pensare a una soluzione, chiedi alla comunità; se dopotutto non c'è una soluzione facile, poi  sentiti libero di raggiungere il jQuery. Ma non lasciare jQuery diventare una stampella o non sarai mai padrone di AngularJS.

3. Pensa sempre in termini di architettura

Prima lo sai applicazioni a pagina singola  siamo applicazioni . Sono non  pagine web. Quindi dobbiamo pensare come uno sviluppatore lato server Inoltre  pensare come uno sviluppatore sul lato client. Dobbiamo pensare a come dividere la nostra applicazione in componenti singoli, estendibili e testabili.

Allora Come  lo fai? Come si "pensa in AngularJS"? Ecco alcuni principi generali, in contrasto con jQuery.

La vista è il "record ufficiale"

In jQuery, cambiamo la vista a livello di programmazione. Potremmo avere un menu a tendina definito come ul così:

<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 di simile:

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

Quando guardiamo la vista, non è immediatamente ovvio che ci sia qualche funzionalità qui. Per le 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. Nostro ul la dichiarazione sembrerebbe invece questa:

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

Questi due fanno la stessa cosa, ma nella versione AngularJS chiunque guarda il modello sa cosa dovrebbe succedere. Ogni volta che arriva un nuovo membro del team di sviluppo, può guardare a questo e poi conoscere  che c'è una direttiva chiamata dropdownMenu operando su di esso; non ha bisogno di intuire la risposta giusta o setacciare alcun codice. La vista ci diceva cosa doveva succedere. Molto più pulito

Gli sviluppatori nuovi di AngularJS spesso fanno una domanda del tipo: come faccio a trovare tutti i collegamenti di un tipo specifico e ad aggiungere una direttiva su di essi. Lo sviluppatore è sempre sbalordito quando rispondiamo: non lo fai. Ma la ragione per cui non lo fai è che questo è come mezzo-jQuery, mezzo-AngularJS, e non va bene. Il problema qui è che lo sviluppatore sta cercando di "fare jQuery" nel contesto di AngularJS. Non funzionerà mai bene La vista è  il record ufficiale. Al di fuori di una direttiva (più su questo sotto), mai e poi mai, mai  cambia il DOM. E le direttive sono applicate nella vista , quindi l'intento è chiaro.

Ricorda: non progettare e quindi contrassegnare. Devi architetto e quindi progettare.

Associazione dati

Questa è di gran lunga una delle più straordinarie caratteristiche di AngularJS e elimina la necessità di eseguire i tipi di manipolazioni DOM che ho menzionato nella sezione precedente. AngularJS aggiornerà automaticamente la tua vista in modo da non dover! In jQuery, rispondiamo agli eventi e quindi aggiorniamo il contenuto. 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 intenti significanti che ho menzionato prima. Ma ancora più importante, abbiamo dovuto fare riferimento e aggiornare manualmente un nodo DOM. E se vogliamo cancellare una voce di log, dobbiamo codificarci anche contro il DOM. Come testiamo la logica a parte il DOM? E se volessimo cambiare la presentazione?

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

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

E il nostro punto di vista può assomigliare a questo:

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

Ma del resto, 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 usare una lista non ordinata, stiamo usando le caselle di avviso Bootstrap. E non abbiamo mai dovuto cambiare il codice del controller! Ma ancora più importante, non importa dove  o Come  il registro viene aggiornato, anche la vista cambierà. Automaticamente. Neat!

Anche se non l'ho mostrato qui, l'associazione dei dati è bidirezionale. Quindi quei messaggi di registro potrebbero anche essere modificabili nella vista solo facendo così: <input ng-model="entry.msg" />. E c'era molta gioia.

Strato di modello distinto

In jQuery, il DOM è un po 'come il modello. Ma in AngularJS, abbiamo un livello di modello separato che possiamo gestire in qualsiasi modo vogliamo, completamente indipendente dalla vista. Questo aiuta a mantenere l'associazione di dati sopra riportata separazione degli interessi e introduce una testabilità di gran lunga maggiore. Altre risposte hanno menzionato questo punto, quindi mi limiterò a lasciarlo.

Separazione degli interessi

E tutto questo si lega a questo tema fondamentale: mantieni le tue preoccupazioni separate. Il tuo punto di vista funge da record ufficiale di ciò che dovrebbe accadere (per la maggior parte); il tuo modello rappresenta i tuoi dati; si dispone di un livello di servizio per eseguire attività riutilizzabili; fai manipolazione DOM e aumenta la tua visione con le direttive; e lo incolli tutti insieme con i controller. Questo è stato anche menzionato in altre risposte, e l'unica cosa che aggiungerei riguarda la testabilità, che discuterò in un'altra sezione di seguito.

Iniezione di dipendenza

Per aiutarci con la separazione delle preoccupazioni è iniezione di dipendenza  (DI). Se provieni da un linguaggio lato server (da Giava  a PHP Probabilmente hai già familiarità con questo concetto, ma se sei un ragazzo lato cliente 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 è possibile dichiarare i componenti molto liberamente e quindi da qualsiasi altro componente, basta chiedere un'istanza di esso e sarà concesso. Non è necessario conoscere l'ordine di caricamento, i percorsi dei file o simili. Il potere potrebbe non essere immediatamente visibile, ma fornirò un solo esempio (comune): test.

Diciamo che nella nostra applicazione, abbiamo bisogno di un servizio che implementa l'archiviazione sul lato server attraverso a RIPOSO  API e, a seconda dello stato dell'applicazione, anche dello storage locale. Quando eseguiamo test sui nostri controller, non vogliamo dover comunicare con il server: stiamo testando il controllore , Dopotutto. Possiamo semplicemente aggiungere un servizio fittizio con lo stesso nome del nostro componente originale, e l'iniettore assicurerà che il nostro controllore ottenga automaticamente il falso - il nostro controllore non lo fa e non ha bisogno di sapere la differenza.

A proposito di test ...

4. Sviluppo basato sui test - sempre

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

Di tutti i molti plugin jQuery che hai visto, usato o scritto, quanti di loro avevano una suite di test di accompagnamento? Non molti perché jQuery non è molto adatto a questo. Ma AngularJS è.

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

Ma poiché abbiamo una separazione delle preoccupazioni, possiamo fare lo sviluppo basato su test in modo iterativo in AngularJS! Ad esempio, diciamo che vogliamo una direttiva super-semplice per indicare nel nostro menu qual è il nostro attuale percorso. Possiamo dichiarare ciò che vogliamo nella nostra applicazione:

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

Ok, ora possiamo scrivere un test per il non-esistente when-active direttiva:

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

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

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

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 è entrambi  iterativo e  test-driven. Wicked-cool.

5. Concettualmente, le direttive sono non  pacchetto jQuery

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

Ma tuffiamoci un po 'più in profondità ...

Alcune direttive decorano solo ciò che è già nella vista (pensa ngClass) e quindi a volte manipolano DOM direttamente e poi sono praticamente fatti. Ma se una direttiva è come un "widget" e ha un modello, dovrebbe anche  rispettare la separazione delle preoccupazioni. Cioè, il modello pure  dovrebbe rimanere ampiamente indipendente dalla sua implementazione nelle funzioni di collegamento e di controllo.

AngularJS è dotato di un intero set di strumenti per rendere questo molto facile; con ngClass possiamo aggiornare dinamicamente la classe; ngModel consente il collegamento dati bidirezionale; ngShow e ngHide mostra o nasconde un elemento a livello di programmazione; e molti altri, compresi quelli che scriviamo noi stessi. In altre parole, possiamo fare ogni tipo di meraviglia senza  Manipolazione DOM. Minore è la manipolazione del DOM, le verifiche più semplici sono da testare, più facile è lo stile, più è facile cambiarle in futuro e più sono riutilizzabili e distribuibili.

Vedo molti sviluppatori nuovi in ​​AngularJS che usano le direttive come luogo in cui lanciare un sacco di jQuery. In altre parole, pensano "dal momento che non posso manipolare DOM nel controller, prenderò quel codice metterlo in una direttiva". Mentre questo è certamente molto meglio, è spesso ancora sbagliato .

Pensa al logger programmato nella sezione 3. Anche se lo inseriamo in una direttiva, noi ancora  voglio farlo il "modo angolare". esso ancora  non prende alcuna manipolazione DOM! Ci sono molte volte in cui la manipolazione del DOM è necessaria, ma è a lotto  più raro di quanto pensi! Prima di manipolare DOM dovunque  nella tua applicazione, chiediti se davvero ne hai bisogno. Potrebbe esserci un modo migliore.

Ecco un rapido esempio che mostra il modello che vedo più frequentemente. Vogliamo un pulsante modificabile. (Nota: questo esempio è un po 'inventato e uno skosh verboso per rappresentare casi più complicati che sono risolti esattamente nello 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. Non c'è niente che abbiamo fatto qui che ha richiesto jQuery!
  2. Secondo, anche se abbiamo già jQuery sulla nostra pagina, non c'è motivo di usarlo qui; possiamo semplicemente usare angular.element e il nostro componente funzionerà ancora quando viene rilasciato in un progetto che non ha jQuery.
  3. Terzo, anche assumendo jQuery era  richiesto per questa direttiva per funzionare, jqLite ( angular.element) volere sempre  usa 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 includere gli elementi jqLite $ - il element quello è passato al link funzione sarebbe già essere  un elemento jQuery!
  5. E quinto, che abbiamo menzionato nelle sezioni precedenti, perché stiamo mescolando i modelli alla nostra logica?

Questa direttiva può essere riscritta (anche per casi molto complicati!) Molto più semplicemente in questo modo:

.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 (oi tuoi utenti) puoi facilmente sostituirlo con uno che soddisfi qualsiasi stile necessario, e logica  non ho mai dovuto essere toccato. Riusabilità - boom!

E ci sono ancora tutti quegli altri vantaggi, come testare: è facile! Indipendentemente dal modello, l'API interna della direttiva non viene mai toccata, quindi il refactoring è semplice. È possibile modificare il modello quanto si desidera senza toccare la direttiva. E non importa cosa cambi, i tuoi test continuano a passare.

w00t!

Quindi se le direttive non sono solo raccolte di funzioni simili a jQuery, quali sono? Le direttive sono in realtà estensioni di HTML . Se HTML non fa qualcosa che ti serve, scrivi una direttiva per farlo per te, e poi usalo come se fosse parte dell'HTML.

In altre parole, se AngularJS non fa qualcosa fuori dalla scatola, pensa a come il team lo realizzerebbe per adattarsi perfettamente ngClick, ngClass, et al.

Sommario

Non usare nemmeno jQuery. Non includerlo nemmeno. Ti terrà indietro. E quando arrivi a un problema che pensi di sapere già come risolvere in jQuery, prima di raggiungere il $, prova a pensare a come farlo all'interno del AngularJS. Se non lo sai, chiedi! 19 volte su 20, il modo migliore per farlo non richiede jQuery e cercare di risolverlo con risultati di jQuery in più lavoro per te.


7187
2018-02-21 21:26



Imperativo → dichiarativo

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

In AngularJS, vuoi pensarci visualizzazioni  piuttosto che elementi DOM. Le viste sono HTML (dichiarativi) che contengono AngularJS direttive . Le direttive impostano i gestori di eventi dietro le quinte per noi e ci forniscono dati dinamici. I selettori vengono usati raramente, quindi la necessità di ID (e alcuni tipi di classi) è notevolmente ridotta. Le viste sono legate a Modelli  (via gli ambiti). Le viste sono una proiezione del modello. Gli eventi modificano i modelli (ovvero i dati, le proprietà degli ambiti) e le viste che proiettano tali modelli "automaticamente".

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

Separazione degli interessi

jQuery impiega JavaScript non invadente  - comportamento (JavaScript) è separato dalla struttura (HTML).

AngularJS utilizza controllori  e direttive (ognuna delle 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 aiutare a separare / organizzare la tua applicazione.

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

Design 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 vuoi presentare i tuoi modelli: i tuoi punti di vista. Crea modelli HTML per ogni vista, utilizzando le direttive necessarie per ottenere l'associazione dinamica dei dati.
  3. Collegare un controller a ciascuna vista (utilizzando ng-view e routing o ng-controller). Chiedere al controller di trovare / ottenere solo i dati del modello necessari alla vista per svolgere il proprio lavoro. Riduci al minimo i controller.

Eredità prototipale

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


408
2018-02-21 04:09



AngularJS vs. jQuery

AngularJS e jQuery adottano ideologie molto diverse. Se vieni da jQuery potresti trovare alcune differenze sorprendenti. Angolare potrebbe farti arrabbiare.

Questo è normale, dovresti farcela. Angolare ne vale la pena.

La grande differenza (TLDR)

jQuery ti offre un toolkit per selezionare bit arbitrari del DOM e apportare modifiche ad hoc ad essi. 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, sembra specifico direttive  (direttive del compilatore) che dicono al compilatore di AngularJS come comportarsi e cosa fare. Le direttive sono piccoli oggetti pieni di JavaScript che possono essere confrontati con attributi, tag, classi o persino commenti.

Quando il compilatore angolare determina che una parte del DOM corrisponde a una particolare direttiva, chiama la funzione direttiva, passandogli l'elemento DOM, eventuali attributi, l'attuale $ scope (che è un archivio di variabili locali) e alcuni altri utili bit. Questi attributi possono contenere espressioni che possono essere interpretate dalla Direttiva e che indicano come eseguire il rendering e quando deve ridisegnarsi.

Le direttive possono quindi a loro volta aggiungere ulteriori componenti angolari come controller, servizi, ecc. Ciò che esce dal fondo del compilatore è un'applicazione web completamente formata, cablata e pronta all'uso.

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

Se questo suona come potrebbe essere eccessivamente prescrittivo e limitante, nulla potrebbe essere più lontano dalla verità. Poiché AngularJS tratta il tuo codice HTML come codice, ottieni Granularità del livello HTML nella tua applicazione web . Tutto è possibile e la maggior parte delle cose è sorprendentemente facile una volta fatti alcuni salti concettuali.

Andiamo al nocciolo duro.

Innanzitutto, Angular non sostituisce jQuery

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

A Misko piace jQuery e non si oppone a te che lo usi. Tuttavia, scoprirai che avanzando puoi ottenere praticamente tutto il lavoro svolto utilizzando una combinazione di ambito, modelli e direttive e dovresti preferire questo flusso di lavoro dove possibile, perché il tuo codice sarà più discreto, più configurabile e più Angolare.

Se usi jQuery, non dovresti spargerlo dappertutto. La posizione corretta per la manipolazione del DOM in AngularJS è in una direttiva. Maggiori informazioni su questi più tardi.

JavaScript discreto con i selettori rispetto ai modelli dichiarativi

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

Il JavaScript ha il controllo. L'HTML ha un'esistenza completamente indipendente. Il tuo HTML rimane semantico anche senza JavaScript. Gli attributi di onclick sono pessime pratiche.

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

Quando la vedi per la prima volta, potresti essere tentato di scrivere AngularJS come JavaScript intrusivo della vecchia scuola (come ho fatto all'inizio). In effetti, AngularJS non gioca con quelle regole. In AngularJS, il tuo HTML5 è un modello. È 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 codice HTML è codice da compilare. AngularJS legge l'intera pagina Web e la compila letteralmente in una nuova pagina Web utilizzando il compilatore incorporato.

Il tuo modello dovrebbe essere dichiarativo; il suo significato dovrebbe essere chiaro semplicemente leggendolo. Usiamo attributi personalizzati con nomi significativi. Creiamo nuovi elementi HTML, sempre con nomi significativi. Un designer con una conoscenza minima dell'HTML e nessuna capacità 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 è nel posto di guida.

Una delle prime domande che mi sono posto all'avvio di AngularJS e nell'esecuzione delle esercitazioni è "Dov'è il mio codice?" . Non ho scritto JavaScript, eppure ho tutto questo comportamento. La risposta è ovvia. Poiché AngularJS compila il DOM, AngularJS tratta il codice HTML come codice. Per molti semplici casi è spesso sufficiente scrivere semplicemente 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 componenti AngularJS e AngularJS si occuperà di inserirli e renderli disponibili al momento giusto in base alla struttura del modello. Questo è molto diverso da uno standard MVC  modello, dove il modello è solo per l'output.

È più simile a XSLT  di Ruby on Rails  per esempio.

Questa è un'inversione radicale del controllo a cui ci si deve abituare.

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

HTML semantico contro modelli semantici

Con jQuery la tua pagina HTML dovrebbe contenere contenuti semantici e significativi. Se il JavaScript è disattivato (da un utente o da un motore di ricerca) il tuo contenuto rimane accessibile.

Perché AngularJS tratta la tua pagina HTML come un modello. Il modello non dovrebbe essere semantico in quanto il contenuto è in genere memorizzato nel modello che in definitiva proviene dalla tua 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 visualizzazione.

A questo punto è probabile che abbiate 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 ajaxed  soddisfare. Tuttavia, vorrai assicurarti di utilizzare gli URL pushstate e di avere una sitemap decente. Vedi qui per una discussione sul problema: https://stackoverflow.com/a/23245379/687677

Separazione delle preoccupazioni (SOC) vs. MVC

Separazione degli interessi  (SOC) è un modello che è cresciuto in molti anni di sviluppo web per una serie di motivi, tra cui SEO, accessibilità e incompatibilità con il browser. Sembra questo:

  1. HTML - Significato semantico. L'HTML dovrebbe stare da solo.
  2. CSS - Styling, senza il 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, AngularJS elimina un decennio di saggezza ricevuta  e invece implementa un pattern MVC in cui il modello non è più semantico, nemmeno un po '.

Sembra questo:

  1. Modello: i tuoi modelli contengono i tuoi dati semantici. I modelli sono di solito JSON  oggetti. I modelli esistono come attributi di un oggetto chiamato $ scope. È anche possibile memorizzare utili funzioni di utilità su $ scope a cui i modelli possono accedere.
  2. Visualizza: le tue visualizzazioni sono scritte in HTML. La vista di solito non è semantica perché i tuoi dati sono presenti 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, è possibile o meno necessario creare un controller. Puoi avere molti controller su una pagina.

MVC e SOC non si trovano su estremità opposte della stessa scala, sono su assi completamente diversi. Il 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 contro Direttive

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

In jQuery definiamo i plugin aggiungendo funzioni al 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 desideri un carosello sulla tua pagina, puoi definire un elenco non ordinato di figure, magari racchiuso in un elemento di navigazione. Potresti quindi scrivere jQuery per selezionare l'elenco sulla pagina e ridistribuirlo 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 a loro. Le direttive sono collegate al modello utilizzando gli attributi o gli elementi che hai inventato. L'idea è di estendere le capacità dell'HTML con nuovi attributi ed elementi.

Il modo AngularJS è di estendere le capacità di HTML nativo.  Dovresti scrivere HTML simile a HTML, esteso con attributi ed elementi personalizzati.

Se vuoi una giostra, usa solo a <carousel /> elemento, quindi definisci una direttiva per inserire un modello e fai in modo che quel pollone funzioni.

Un sacco di piccole direttive contro grandi plugin con switch di configurazione

La tendenza con jQuery è quella di scrivere grandi plugin 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 scrivi un plug-in dropdown potresti essere tentato di inserire codice in click handler, forse una funzione da aggiungere in un gallone che è su o giù, forse cambia la classe dell'elemento unfolded, mostra nascondi il menu, tutte le cose utili.

Fino a quando non vuoi fare un piccolo cambiamento.

Di 'che hai un menu che vuoi spiegare al passaggio del mouse. Bene, ora abbiamo un problema. Il nostro plug-in è stato collegato al nostro gestore di clic per noi, avremo bisogno di aggiungere un'opzione di configurazione per farlo comportare diversamente in questo caso specifico.

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

Adesso nel nostro modello  possiamo collegarlo:

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

Devi aggiornare il mouseover?

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

Il modello guida l'applicazione in modo da ottenere granularità a livello HTML. Se vogliamo fare eccezioni caso per caso, il modello rende tutto ciò facile.

Chiusura contro $ scope

I plugin JQuery sono creati in una chiusura. La privacy è mantenuta all'interno di quella chiusura. Sta a te mantenere la catena di portata entro quella chiusura. Hai solo veramente accesso al set di nodi DOM passati al plugin da jQuery, più eventuali variabili locali definite nella chiusura e qualsiasi globale 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 si memorizza il modello. Alcune direttive genereranno un nuovo $ scope, che per impostazione predefinita eredita dal suo ambito $ wrapping utilizzando 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 in modo approssimativo la struttura del DOM, gli elementi hanno accesso al proprio ambito e agli eventuali ambiti di contenimento senza soluzione di continuità, fino all'intero scope $ globale (che non è lo stesso dell'ambito globale).

Ciò semplifica notevolmente il trasferimento dei dati e il salvataggio dei dati a un livello appropriato. Se un dropdown è aperto, solo il dropdown $ scope deve saperlo. Se l'utente aggiorna le proprie preferenze, è possibile aggiornare l'ambito $ globale e tutti gli ambiti nidificati che ascoltano le preferenze dell'utente verranno automaticamente avvisati.

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

Cambiamenti manuali DOM rispetto a Binding dati

In jQuery fai tutte le tue modifiche DOM manualmente. Costruisci nuovi elementi DOM in modo programmatico. 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 ad utilizzare l'associazione dati. Cambia il tuo modello e poiché il DOM è associato ad esso tramite un modello che il tuo DOM aggiornerà automaticamente, non è richiesto alcun intervento.

Poiché l'associazione dei dati viene eseguita dal modello, utilizzando un attributo o la sintassi della parentesi graffa, è semplicissimo da eseguire. C'è poco overhead cognitivo associato ad esso quindi ti troverai a farlo tutto il tempo.

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

Lega l'elemento di input a $scope.user.name. L'aggiornamento dell'ingresso aggiornerà il valore nel campo di applicazione corrente e viceversa.

Allo stesso modo:

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

produrrà il nome utente in un paragrafo. È un legame dal vivo, quindi se il $scope.user.name il valore è aggiornato, anche il modello verrà aggiornato.

Ajax tutto il tempo

In jQuery fare una chiamata Ajax è abbastanza semplice, ma è ancora qualcosa su cui potresti pensarci due volte. C'è l'ulteriore complessità a cui pensare e un bel pezzo di script da mantenere.

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

Service Objects vs Helper Functions

In jQuery, se vogliamo eseguire una piccola attività non correlata alla dom, ad esempio 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 singleton, nel senso che non possono mai essere più di uno di loro. Diciamo che vogliamo accedere all'API di overflow dello stack, potremmo scrivere a StackOverflowService che definisce i metodi per farlo.

Diciamo che abbiamo un carrello della spesa. Potremmo definire un ShoppingCartService che mantiene il nostro carrello e contiene metodi per aggiungere e rimuovere elementi. Poiché il servizio è un singleton, ed è condiviso da tutti gli altri componenti, qualsiasi oggetto che deve scrivere nel carrello degli acquisti e ricavare i dati da esso. È sempre lo stesso carrello.

Gli oggetti di servizio sono componenti AngularJS autonomi che possiamo usare e riutilizzare come meglio crediamo. Sono semplici oggetti JSON contenenti funzioni e dati. Sono sempre singleton, quindi se memorizzi i dati su un servizio in un posto, puoi ottenere quei dati da qualche altra parte semplicemente richiedendo lo stesso servizio.

Iniezione di dipendenza  (DI) contro Instatiation - aka de-spaghettification

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

Fino a quando non inizi ad usarlo, è difficile spiegare quale enorme vantaggio vada a fare. 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, ciascuno 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 che può accedere a Flickr, ho solo bisogno di fare riferimento al 'FlickrService' per nome quando dichiaro il controller. AngularJS si occuperà di istanziare il 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 per nome come questo:

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

AngularJS riconoscerà che un oggetto FlickrService è necessario per istanziare il controller e ne fornirà uno per noi.

Ciò semplifica le operazioni di cablaggio e elimina praticamente ogni tendenza alla spagettificazione. Abbiamo una lista di componenti piatta, e AngularJS li consegna a uno a 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 includere tutte le funzioni relative a Flickr. I moduli possono includere altri moduli (DI). L'applicazione principale di solito è un modulo e questo dovrebbe includere tutti gli altri moduli da cui dipenderà l'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 di quel modulo diventano disponibili come elenco semplice identificato dalle loro stringhe univoche . Possiamo quindi iniettare questi componenti l'uno nell'altro utilizzando il meccanismo di iniezione delle dipendenze di AngularJS.

Per riassumere

AngularJS e jQuery non sono nemici. È possibile utilizzare jQuery in AngularJS molto bene. Se stai utilizzando AngularJS bene (modelli, associazione dati, $ scope, direttive, ecc.) Troverai che hai bisogno di lotto  meno jQuery di quanto potrebbe 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 delle piccole direttive che fanno una cosa, poi scrivi un semplice modello per collegarle insieme.

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

Il mio piccolo libro

Sono così entusiasta di AngularJS, ho scritto un breve libro su di esso che sei molto lieto di leggere online http://nicholasjohnson.com/angular-book/ . Spero sia utile.


184
2018-05-12 10:22



Puoi descrivere il cambio di paradigma che è 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 su questo Qui . Inoltre, controlla la risposta di Mark Rajcok.

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

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

Qual è la più grande differenza? 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 , dati vincolanti e molto altro.

Si concentra su separazione degli interessi  e test ( test unitario  e test end-to-end), che facilita lo sviluppo basato sui test.

Il modo migliore per iniziare sta attraversando il loro fantastico tutorial . Puoi passare attraverso i passaggi in un paio d'ore; tuttavia, nel caso in cui desideri dominare i concetti dietro le quinte, includono una miriade di riferimenti per ulteriori letture.

Esistono considerazioni / restrizioni sul lato server?

Puoi usarlo su applicazioni esistenti dove stai già utilizzando jQuery puro. Tuttavia, se si desidera sfruttare appieno le funzionalità di AngularJS, è possibile prendere in considerazione la codifica del lato server utilizzando a Riposante  approccio.

Fare così ti permetterà di sfruttare il loro fabbrica di risorse , che crea un'astrazione del lato server RESTful API  e rende le chiamate lato server (ottieni, salva, cancella, ecc.) incredibilmente facile.


152
2018-02-21 04:29



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

AngularJS cambia il tuo modo di vedere trova  elementi

In jQuery , di solito lo usi selettori  per trovare elementi e quindi collegarli:
$('#id .class').click(doStuff);

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

AngularJS non ha bisogno (o vuole) di trovare elementi usando selettori - la differenza principale tra AngularJS jqLite  contro pieno jQuery  è questo jqLite non supporta i selettori .

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


84
2018-02-21 07:57



jQuery

jQuery rende comandi JavaScript incredibilmente lunghi come getElementByHerpDerp più corto e cross-browser.

AngularJS

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

Modificare:

Dicendo "Ho uno sfondo jQuery come posso pensare in AngularJS?" è come dire "Ho uno sfondo HTML come faccio a pensare in JavaScript?" Il fatto che tu stia ponendo la domanda mostra 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 la lista dicendo "AngularJS fa uso di direttive considerando che jQuery usa i selettori CSS per creare un oggetto jQuery che fa questo e quello ecc ...." . Questa domanda non richiede una lunga risposta.

jQuery è un modo per semplificare la programmazione di JavaScript nel browser. Brevi comandi cross-browser, ecc.

AngularJS estende HTML, quindi non devi metterlo <div> dappertutto solo per fare un'applicazione. Rende l'HTML effettivamente funzionante per le applicazioni piuttosto che per quello per cui è stato progettato, che è statico, pagine web educative. Compie questo in modo indiretto usando JavaScript, ma fondamentalmente si tratta di un'estensione di HTML, non di JavaScript.


69
2018-02-04 05:07



jQuery: tu pensi molto a 'QUERYing the DOM 'per elementi DOM e fare qualcosa.

AngularJS: THE model is the truth, e tu pensi sempre da quell'ANGLE.

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 / APPENDA 'lì creando un nuovo nodo o semplicemente impostando il suo innerHTML . Quindi, quando vuoi aggiornare questa vista, allora '3. TROVA 'la posizione e' 4. AGGIORNARE'. Questo ciclo di ricerca e aggiornamento eseguito nello stesso contesto di recupero e formattazione dei dati dal server è disponibile in AngularJS.

Con AngularJS hai il tuo modello (oggetti JavaScript a cui sei già abituato) e il valore del modello ti parla del modello (ovviamente) e della vista, e un'operazione sul modello si propaga automaticamente alla vista, quindi non lo fai Devo pensarci. Ti troverai in AngularJS non trovando più cose nel DOM.

Per dirla in un altro modo, in jQuery, devi pensare ai selettori CSS, cioè, dove si trova il div o td che ha una classe o un attributo, ecc., in modo che io possa ottenere il loro HTML o colore o valore, ma in AngularJS, ti troverai a pensare in questo modo: di quale modello mi occupo, imposterò il valore del modello su true. Non ti stai preoccupando se la vista che riflette questo valore è una casella selezionata o risiede in a td elemento (i dettagli che avresti spesso avuto bisogno di pensare in jQuery).

E con la manipolazione del DOM in AngularJS, ti ritrovi ad aggiungere direttive e filtri, che 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 benefici ne valgono la pena, quindi imparare AngularJS di solito significa imparare ciò che AngularJS vuole o il modo in cui AngularJS richiede che tu presenti le tue funzioni e lo chiamerà di conseguenza. Questa è una delle cose che rende AngularJS un framework piuttosto che una libreria.


61
2017-11-02 16:53



Queste sono alcune risposte molto belle, ma lunghe.

Per riassumere le mie esperienze:

  1. Controller e provider (servizi, fabbriche, ecc.) Servono per modificare il modello di dati, NON HTML.
  2. HTML e direttive definiscono il layout e il binding al modello.
  3. Se è necessario condividere i dati tra i controllori, creare un servizio o una fabbrica, sono singoletti condivisi nell'applicazione.
  4. Se hai bisogno di un widget HTML, crea una direttiva.
  5. Se hai alcuni dati e stai provando ad aggiornare HTML ... STOP! aggiorna il modello e assicurati che il tuo codice HTML sia associato al modello.

46
2018-05-16 21:50



jQuery è una libreria di manipolazione DOM.

AngularJS è un framework MV *.

In effetti, AngularJS è uno dei pochi framework MV * JavaScript (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 una edizione jQuery-lite al suo interno. Quindi, per alcune selezioni / manipolazioni DOM di base, non è necessario includere la libreria jQuery (salva molti byte da eseguire 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 il ​​bisogno di fare cose relative alla manipolazione DOM (le direttive sono solo un posto dove dovresti scrivere il codice jQuery mentre usi AngularJS).

AngularJS implica una curva di apprendimento (più di jQuery :-).

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

In bocca al lupo.


45
2017-10-10 08:58