«Penser dans AngularJS» si j'ai un arrière-plan jQuery? [fermé]

4514

Supposons que je connaisse le développement d'applications côté client dans jQuery , mais maintenant j'aimerais commencer à utiliser AngularJS . Pouvez-vous décrire le changement de paradigme qui est nécessaire? Voici quelques questions qui pourraient vous aider à formuler une réponse:

  • Comment puis-je architecturer et concevoir différemment les applications Web côté client? Quelle est la plus grande différence?
  • Que dois-je arrêter de faire / d'utiliser; Que dois-je commencer à faire / utiliser à la place?
  • Y a-t-il des considérations / restrictions côté serveur?

Je ne cherche pas une comparaison détaillée entre jQueryet AngularJS.

Mark Rajcok
la source
Pour ceux qui connaissent "ASP.NET MVC" ou "RoR" - il suffit de penser à Angular comme à "MVC côté client" et c'est tout.
Serge Shultz

Réponses:

7178

1. Ne concevez pas votre page, puis modifiez-la avec des manipulations DOM

Dans jQuery, vous concevez une page, puis vous la rendez dynamique. Cela est dû au fait que jQuery a été conçu pour une augmentation et s'est considérablement développé à partir de cette simple prémisse.

Mais dans AngularJS, vous devez partir de zéro avec votre architecture à l'esprit. Au lieu de commencer par penser "J'ai ce morceau du DOM et je veux le faire faire X", vous devez commencer par ce que vous voulez accomplir, puis concevoir votre application, puis enfin concevoir votre vue.

2. N'augmentez pas jQuery avec AngularJS

De même, ne commencez pas avec l'idée que jQuery fait X, Y et Z, donc je vais juste ajouter AngularJS en plus pour les modèles et les contrôleurs. C'est vraiment tentant lorsque vous débutez, c'est pourquoi je recommande toujours aux nouveaux développeurs AngularJS de ne pas utiliser jQuery du moins, du moins jusqu'à ce qu'ils s'habituent à faire les choses de la "manière angulaire".

J'ai vu de nombreux développeurs ici et sur la liste de diffusion créer ces solutions élaborées avec des plugins jQuery de 150 ou 200 lignes de code qu'ils collent ensuite dans AngularJS avec une collection de rappels et de $applys qui sont déroutants et compliqués; mais ils finissent par le faire fonctionner! Le problème est que dans la plupart des cas, ce plugin jQuery pourrait être réécrit dans AngularJS dans une fraction du code, où tout devient soudainement compréhensible et simple.

La ligne de fond est la suivante: lors de la résolution, d'abord "pensez à AngularJS"; si vous ne trouvez pas de solution, demandez à la communauté; si après tout cela il n'y a pas de solution facile, alors n'hésitez pas à contacter jQuery. Mais ne laissez pas jQuery devenir une béquille ou vous ne maîtriserez jamais AngularJS.

3. Toujours penser en termes d'architecture

Sachez d'abord que les applications d'une seule page sont des applications . Ce ne sont pas des pages Web. Nous devons donc penser comme un développeur côté serveur en plus de penser comme un développeur côté client. Nous devons réfléchir à la façon de diviser notre application en composants individuels, extensibles et testables.

Alors, comment faites-vous cela? Comment "pensez-vous dans AngularJS"? Voici quelques principes généraux, contrastés avec jQuery.

La vue est le "record officiel"

Dans jQuery, nous modifions la vue par programmation. Nous pourrions avoir un menu déroulant défini ulcomme ceci:

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

Dans jQuery, dans notre logique d'application, nous l'activerions avec quelque chose comme:

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

Lorsque nous regardons simplement la vue, il n'est pas immédiatement évident qu'il existe une fonctionnalité ici. Pour les petites applications, c'est bien. Mais pour les applications non triviales, les choses deviennent rapidement confuses et difficiles à entretenir.

Dans AngularJS, cependant, la vue est l'enregistrement officiel de la fonctionnalité basée sur la vue. Notre uldéclaration ressemblerait plutôt à ceci:

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

Ces deux font la même chose, mais dans la version AngularJS, quiconque regarde le modèle sait ce qui est censé se produire. Chaque fois qu'un nouveau membre de l'équipe de développement monte à bord, elle peut regarder cela et savoir alors qu'il existe une directive appelée dropdownMenuopérant dessus; elle n'a pas besoin de comprendre la bonne réponse ou de passer au crible un code. La vue nous a dit ce qui devait arriver. Beaucoup plus propre.

Les développeurs novices d'AngularJS posent souvent une question comme: comment trouver tous les liens d'un type spécifique et y ajouter une directive. Le développeur est toujours sidéré lorsque nous répondons: vous ne le faites pas. Mais la raison pour laquelle vous ne le faites pas, c'est que cela ressemble à moitié jQuery, moitié AngularJS, et pas bon. Le problème ici est que le développeur essaie de "faire jQuery" dans le contexte d'AngularJS. Ça ne marchera jamais bien. La vue est le record officiel. En dehors d'une directive (plus de détails ci-dessous), vous ne changez jamais, jamais, le DOM. Et les directives sont appliquées dans la vue , donc l'intention est claire.

N'oubliez pas: ne concevez pas, puis marquez. Vous devez architecte, puis concevoir.

Liaison de données

C'est de loin l'une des fonctionnalités les plus impressionnantes d'AngularJS et élimine une grande partie du besoin de faire les types de manipulations DOM que j'ai mentionnées dans la section précédente. AngularJS mettra automatiquement à jour votre vue afin que vous n'ayez pas à le faire! Dans jQuery, nous répondons aux événements, puis mettons à jour le contenu. Quelque chose comme:

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

Pour une vue qui ressemble à ceci:

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

Outre le mélange des préoccupations, nous avons également les mêmes problèmes de signifier l'intention que j'ai mentionnés précédemment. Mais plus important encore, nous avons dû référencer et mettre à jour manuellement un nœud DOM. Et si nous voulons supprimer une entrée de journal, nous devons également coder contre le DOM. Comment tester la logique en dehors du DOM? Et si nous voulons changer la présentation?

C'est un peu désordonné et un peu fragile. Mais dans AngularJS, nous pouvons le faire:

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

Et notre point de vue peut ressembler à ceci:

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

Mais d'ailleurs, notre point de vue pourrait ressembler à ceci:

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

Et maintenant, au lieu d'utiliser une liste non ordonnée, nous utilisons des boîtes d'alerte Bootstrap. Et nous n'avons jamais eu à changer le code du contrôleur! Mais plus important encore, peu importe et comment le journal est mis à jour, la vue change également. Automatiquement. Soigné!

Bien que je ne l'aie pas montré ici, la liaison de données est bidirectionnelle. Donc , ces messages journaux peuvent également être modifiables dans la vue juste en faisant ceci: <input ng-model="entry.msg" />. Et il y avait beaucoup de joie.

Couche modèle distincte

Dans jQuery, le DOM est un peu comme le modèle. Mais dans AngularJS, nous avons une couche de modèle distincte que nous pouvons gérer comme bon nous semble, complètement indépendamment de la vue. Cela aide à la liaison de données ci-dessus, maintient la séparation des préoccupations et introduit une testabilité beaucoup plus grande. D'autres réponses ont mentionné ce point, donc je vais en rester là.

Séparation des préoccupations

Et tout ce qui précède est lié à ce thème général: séparez vos préoccupations. Votre point de vue agit comme l'enregistrement officiel de ce qui est censé se produire (pour la plupart); votre modèle représente vos données; vous disposez d'une couche de service pour effectuer des tâches réutilisables; vous faites de la manipulation DOM et augmentez votre vue avec des directives; et vous collez le tout avec des contrôleurs. Cela a également été mentionné dans d'autres réponses, et la seule chose que j'ajouterais concerne la testabilité, dont je discute dans une autre section ci-dessous.

Injection de dépendance

L' injection de dépendance (DI) nous aide à séparer les préoccupations . Si vous venez d'un langage côté serveur (de Java à PHP ), vous connaissez probablement déjà ce concept, mais si vous êtes un gars côté client venant de jQuery, ce concept peut sembler idiot à superflu à hipster . Mais ce n'est pas. :-)

D'un point de vue large, DI signifie que vous pouvez déclarer des composants très librement, puis à partir de tout autre composant, il suffit d'en demander une instance et il vous sera accordé. Vous n'avez pas besoin de connaître l'ordre de chargement, l'emplacement des fichiers ou quelque chose comme ça. La puissance n'est peut-être pas immédiatement visible, mais je ne donnerai qu'un seul exemple (courant): le test.

Disons que dans notre application, nous avons besoin d'un service qui implémente le stockage côté serveur via une API REST et, selon l'état de l'application, un stockage local également. Lors de l'exécution de tests sur nos contrôleurs, nous ne voulons pas avoir à communiquer avec le serveur - nous testons le contrôleur , après tout. Nous pouvons simplement ajouter un service simulé du même nom que notre composant d'origine, et l'injecteur s'assurera que notre contrôleur obtient automatiquement le faux - notre contrôleur ne connaît pas et n'a pas besoin de faire la différence.

En parlant de tests ...

4. Développement piloté par les tests - toujours

Cela fait vraiment partie de la section 3 sur l'architecture, mais il est si important que je le mette dans sa propre section de niveau supérieur.

Sur tous les nombreux plugins jQuery que vous avez vus, utilisés ou écrits, combien d'entre eux avaient une suite de tests d'accompagnement? Pas beaucoup car jQuery n'est pas très réceptif à cela. Mais AngularJS l'est.

Dans jQuery, la seule façon de tester est souvent de créer le composant indépendamment avec une page échantillon / démo sur laquelle nos tests peuvent effectuer une manipulation DOM. Il nous faut donc développer un composant séparément puis l' intégrer dans notre application. Quelle gêne! La plupart du temps, lors du développement avec jQuery, nous optons pour un développement itératif au lieu d'un développement piloté par les tests. Et qui pourrait nous en vouloir?

Mais parce que nous avons une séparation des préoccupations, nous pouvons faire le développement piloté par les tests de manière itérative dans AngularJS! Par exemple, disons que nous voulons une directive super simple pour indiquer dans notre menu quelle est notre route actuelle. Nous pouvons déclarer ce que nous voulons au vu de notre candidature:

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

Bon, maintenant nous pouvons écrire un test pour la when-activedirective inexistante :

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

Et lorsque nous exécutons notre test, nous pouvons confirmer qu'il échoue. Ce n'est que maintenant que nous devons créer notre directive:

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

Notre test passe maintenant et notre menu fonctionne comme demandé. Notre développement est à la fois itératif et piloté par les tests. Wicked-cool.

5. Conceptuellement, les directives ne sont pas empaquetées jQuery

Vous entendrez souvent «ne faire de manipulation DOM que dans une directive». C'est une nécessité. Traitez-le avec déférence!

Mais plongons un peu plus profondément ...

Certaines directives décorent simplement ce qui est déjà dans la vue (pensez ngClass) et font donc parfois une manipulation DOM immédiatement, puis sont essentiellement effectuées. Mais si une directive est comme un "widget" et a un modèle, elle doit également respecter la séparation des préoccupations. Autrement dit, le modèle doit également rester largement indépendant de sa mise en œuvre dans les fonctions de liaison et de contrôleur.

AngularJS est livré avec un ensemble complet d'outils pour rendre cela très facile; avec ngClassnous pouvons mettre à jour dynamiquement la classe; ngModelpermet la liaison de données bidirectionnelle; ngShowet ngHideafficher ou masquer un élément par programmation; et bien d'autres - y compris ceux que nous écrivons nous-mêmes. En d'autres termes, nous pouvons faire toutes sortes de génialités sans manipulation DOM. Moins il y a de manipulation DOM, plus les directives sont faciles à tester, plus elles sont faciles à styliser, plus elles sont faciles à changer à l'avenir, et plus elles sont réutilisables et distribuables.

Je vois beaucoup de développeurs nouveaux dans AngularJS utilisant des directives comme endroit pour lancer un tas de jQuery. En d'autres termes, ils pensent "puisque je ne peux pas faire de manipulation DOM dans le contrôleur, je vais prendre ce code pour le mettre dans une directive". Bien que ce soit certainement beaucoup mieux, c'est souvent encore faux .

Pensez à l'enregistreur que nous avons programmé dans la section 3. Même si nous mettons cela dans une directive, nous voulons toujours le faire de la "manière angulaire". Cela ne prend toujours pas de manipulation DOM! Il y a beaucoup de fois où la manipulation DOM est nécessaire, mais c'est beaucoup plus rare que vous ne le pensez! Avant de faire une manipulation DOM n'importe où dans votre application, demandez-vous si vous en avez vraiment besoin. Il pourrait y avoir une meilleure façon.

Voici un exemple rapide qui montre le motif que je vois le plus souvent. Nous voulons un bouton basculable. (Remarque: cet exemple est un peu artificiel et un skosh verbeux pour représenter des cas plus compliqués qui sont résolus exactement de la même manière.)

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

Il y a quelques problèmes avec cela:

  1. Tout d'abord, jQuery n'a jamais été nécessaire. Nous n'avons rien fait ici qui nécessitait jQuery du tout!
  2. Deuxièmement, même si jQuery est déjà sur notre page, il n'y a aucune raison de l'utiliser ici; nous pouvons simplement utiliser angular.elementet notre composant fonctionnera toujours lorsqu'il est déposé dans un projet qui n'a pas jQuery.
  3. Troisièmement, même en supposant que jQuery était requis pour que cette directive fonctionne, jqLite ( angular.element) utilisera toujours jQuery s'il était chargé! Nous n'avons donc pas besoin d'utiliser le $- nous pouvons simplement utiliser angular.element.
  4. Quatrièmement, étroitement lié au troisième, est que les éléments jqLite n'ont pas besoin d'être encapsulés $- celui elementqui est passé à la linkfonction serait déjà un élément jQuery!
  5. Et cinquièmement, comme nous l'avons mentionné dans les sections précédentes, pourquoi mélangons-nous des éléments de modèle dans notre logique?

Cette directive peut être réécrite (même pour des cas très compliqués!) Beaucoup plus simplement comme ceci:

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

Encore une fois, le modèle est dans le modèle, vous (ou vos utilisateurs) pouvez donc facilement l'échanger contre un qui correspond à n'importe quel style nécessaire, et la logique n'a jamais dû être touchée. Réutilisation - boom!

Et il y a encore tous ces autres avantages, comme les tests - c'est facile! Quel que soit le contenu du modèle, l'API interne de la directive n'est jamais touchée, donc la refactorisation est facile. Vous pouvez modifier le modèle autant que vous le souhaitez sans toucher à la directive. Et peu importe ce que vous changez, vos tests réussissent toujours.

w00t!

Donc, si les directives ne sont pas seulement des collections de fonctions de type jQuery, quelles sont-elles? Les directives sont en fait des extensions de HTML . Si HTML ne fait pas quelque chose dont vous avez besoin, vous écrivez une directive pour le faire pour vous, puis vous l'utilisez comme s'il faisait partie de HTML.

Autrement dit, si AngularJS ne pas faire quelque chose hors de la boîte, pensez comment l'équipe accomplirait pour l' adapter à droite avec ngClick, ngClasset al.

Sommaire

N'utilisez même pas jQuery. Ne l'incluez même pas. Cela vous retiendra. Et lorsque vous arrivez à un problème que vous pensez savoir déjà résoudre dans jQuery, avant d'atteindre le $, essayez de réfléchir à la façon de le faire dans les limites de l'AngularJS. Si vous ne savez pas, demandez! 19 fois sur 20, la meilleure façon de le faire n'a pas besoin de jQuery et d'essayer de le résoudre avec jQuery entraîne plus de travail pour vous.

Josh David Miller
la source
204
Je pense que l'intégration de travailler avec JQuery dans une application angulaire est un cas d'utilisation important en raison de tous les plugins JQuery existants qui ont été écrits. Je ne réécris pas FancyBox dans jQuery pour garder une application angulaire pure.
taudep
119
@taudep Je ne pense pas que nous soyons en désaccord autant que vous le pensez. La plupart des plugins jQuery peuvent être réécrits dans AngularJS à moindre coût, et dans ces cas, nous devrions le faire. Pour quelque chose de complexe pour lequel il n'y a pas d'équivalent, allez-y. Pour citer la section 2: «Le résultat est le suivant: lors de la résolution, commencez par« penser dans AngularJS »; si vous ne trouvez pas de solution, demandez à la communauté; si après tout cela il n'y a pas de solution facile, alors n'hésitez pas à contacter jQuery . Mais ne laissez pas jQuery devenir une béquille ou vous ne maîtriserez jamais AngularJS. [pas d'italique dans l'original]
Josh David Miller
67
un chinois se traduit par cette excellente réponse, espérons utile. hanzheng.github.io/tech/angularjs/2013/10/28/…
Han Zheng
18
@Benno Ce qu'il veut dire par "pas de manipulation DOM", c'est que votre code dans la directive n'exécute pas directement les manipulations DOM. Ce code ne sait rien du DOM, il ne fait que modifier les variables js dans votre modèle. Oui, le résultat final est que le DOM est modifié, mais c'est parce qu'en dehors du code que nous écrivons, il existe des liaisons qui réagissent au changement de nos variables, mais à l'intérieur de la directive, nous ne savons rien à ce sujet, faisant une séparation nette entre la manipulation du DOM et logique métier. Dans votre exemple jQuery, vous changez directement le DOM en disant "ajoutez ce texte à cet élément"
wired_in
11
@trusktr Si un développeur définit la valeur d'un élément d'entrée à l'aide de jQuery dans une application AngularJS, il commet une grave erreur. La seule exception à laquelle je peux penser est un plugin jQuery existant trop difficile à porter qui modifie une entrée automatiquement, auquel cas se connecter à un rappel ou définir une montre est absolument essentiel de toute façon pour apporter les modifications en ligne avec l'application.
Josh David Miller
407

Impératif → déclaratif

Dans jQuery, les sélecteurs sont utilisés pour rechercher des éléments DOM , puis leur lier / enregistrer des gestionnaires d'événements. Lorsqu'un événement se déclenche, ce code (impératif) s'exécute pour mettre à jour / modifier le DOM.

Dans AngularJS, vous voulez penser aux vues plutôt qu'aux éléments DOM. Les vues sont du HTML (déclaratif) contenant des directives AngularJS . Les directives configurent les gestionnaires d'événements en arrière-plan pour nous et nous donnent une liaison de données dynamique. Les sélecteurs sont rarement utilisés, de sorte que le besoin d'ID (et de certains types de classes) est considérablement diminué. Les vues sont liées aux modèles (via des étendues). Les vues sont une projection du modèle. Les événements modifient les modèles (c'est-à-dire les données, les propriétés d'étendue) et les vues qui projettent ces modèles sont mises à jour «automatiquement».

Dans AngularJS, pensez aux modèles, plutôt qu'aux éléments DOM sélectionnés par jQuery qui contiennent vos données. Considérez les vues comme des projections de ces modèles, plutôt que d'enregistrer des rappels pour manipuler ce que l'utilisateur voit.

Séparation des préoccupations

jQuery utilise du JavaScript discret - le comportement (JavaScript) est séparé de la structure (HTML).

AngularJS utilise des contrôleurs et des directives (chacun pouvant avoir son propre contrôleur et / ou des fonctions de compilation et de liaison) pour supprimer le comportement de la vue / structure (HTML). Angular propose également des services et des filtres pour vous aider à séparer / organiser votre application.

Voir également https://stackoverflow.com/a/14346528/215945

Conception d'application

Une approche pour concevoir une application AngularJS:

  1. Pensez à vos modèles. Créez des services ou vos propres objets JavaScript pour ces modèles.
  2. Réfléchissez à la façon dont vous souhaitez présenter vos modèles - vos vues. Créez des modèles HTML pour chaque vue, en utilisant les directives nécessaires pour obtenir une liaison de données dynamique.
  3. Attachez un contrôleur à chaque vue (en utilisant ng-view et routage, ou ng-controller). Demandez au contrôleur de trouver / obtenir uniquement les données de modèle dont la vue a besoin pour faire son travail. Rendez les contrôleurs aussi fins que possible.

Héritage prototypique

Vous pouvez faire beaucoup avec jQuery sans savoir comment fonctionne l'héritage prototypique JavaScript. Lors du développement d'applications AngularJS, vous éviterez certains pièges courants si vous avez une bonne compréhension de l'héritage JavaScript. Lecture recommandée: Quelles sont les nuances de l'héritage prototypique / prototypique de portée dans AngularJS?

Mark Rajcok
la source
1
pouvez-vous pls. expliquer en quoi un élément dom est différent d'une vue?
Rajkamal Subramanian
22
@rajkamal, un élément DOM est (évidemment) un seul élément, et dans jQuery c'est souvent ce que nous sélectionnons / ciblons / manipulons. Une vue angulaire est une collection / un modèle d'éléments DOM associés: vue de menu, vue d'en-tête, vue de pied de page, vue de la barre latérale droite, vue de profil, peut-être plusieurs vues de contenu principal (commutables via ng-view). Fondamentalement, vous souhaitez diviser vos pages en différentes vues. Chaque vue a son propre contrôleur associé. Chaque vue projette une partie de vos modèles.
Mark Rajcok
3
jQuery n'est PAS impératif. onet whensont des fonctions d'ordre supérieur, fonctionnant sur les membres d'un objet de collection jQuery.
Jack Viers
18
Alors, quel type de code est exécuté dans le rappel on? Impératif.
cwharris
5
Cet impératif vs déclaratif n'est vraiment qu'une question d'abstractions. Au final, tout le code déclaratif (que faire) est implémenté impérativement (comment le faire) soit par le développeur dans un sous-programme à un niveau d'abstraction inférieur, par le framework ou un compilateur / interprète. Dire que "jQuery est impératif" en général est une déclaration assez étrange, d'autant plus qu'il fournit en fait une API beaucoup plus déclarative en ce qui concerne la manipulation DOM "manuelle".
Alex
184

AngularJS vs jQuery

AngularJS et jQuery adoptent des idéologies très différentes. Si vous venez de jQuery, certaines des différences peuvent vous surprendre. Angulaire peut vous mettre en colère.

C'est normal, vous devez pousser à travers. Angulaire en vaut la peine.

La grande différence (TLDR)

jQuery vous donne une boîte à outils pour sélectionner des bits arbitraires du DOM et leur apporter des modifications ad hoc. Vous pouvez faire à peu près tout ce que vous aimez, morceau par morceau.

AngularJS vous donne plutôt un compilateur .

Cela signifie que AngularJS lit l'intégralité de votre DOM de haut en bas et le traite comme du code, littéralement comme des instructions pour le compilateur. En parcourant le DOM, il recherche des directives spécifiques ( directives du compilateur) qui indiquent au compilateur AngularJS comment se comporter et quoi faire. Les directives sont de petits objets pleins de JavaScript qui peuvent correspondre à des attributs, des balises, des classes ou même des commentaires.

Lorsque le compilateur angulaire détermine qu'un morceau du DOM correspond à une directive particulière, il appelle la fonction directive, en lui passant l'élément DOM, tous les attributs, le $ scope actuel (qui est un magasin de variables local) et quelques autres bits utiles. Ces attributs peuvent contenir des expressions qui peuvent être interprétées par la directive et qui lui indiquent comment effectuer le rendu et quand il doit se redessiner.

Les directives peuvent ensuite à leur tour extraire des composants angulaires supplémentaires tels que des contrôleurs, des services, etc. Ce qui sort du bas du compilateur est une application Web entièrement formée, câblée et prête à fonctionner.

Cela signifie que Angular est piloté par modèle . Votre modèle pilote le JavaScript, et non l'inverse. Il s'agit d'un renversement radical des rôles, et l'opposé complet du JavaScript discret que nous écrivons depuis une dizaine d'années. Cela peut prendre un certain temps pour s'y habituer.

Si cela semble être trop contraignant et limitatif, rien ne pourrait être plus éloigné de la vérité. Étant donné qu'AngularJS traite votre code HTML comme du code, vous obtenez une granularité de niveau HTML dans votre application Web . Tout est possible, et la plupart des choses sont étonnamment faciles une fois que vous avez fait quelques sauts conceptuels.

Venons-en aux choses sérieuses.

Tout d'abord, Angular ne remplace pas jQuery

Angular et jQuery font des choses différentes. AngularJS vous fournit un ensemble d'outils pour produire des applications Web. jQuery vous donne principalement des outils pour modifier le DOM. Si jQuery est présent sur votre page, AngularJS l'utilisera automatiquement. Si ce n'est pas le cas, AngularJS est livré avec jQuery Lite, qui est une version réduite, mais toujours parfaitement utilisable de jQuery.

Misko aime jQuery et ne s'oppose pas à ce que vous l'utilisiez. Cependant, vous constaterez à mesure que vous progressez que vous pouvez effectuer à peu près tout votre travail en utilisant une combinaison de portée, de modèles et de directives, et vous devriez préférer ce flux de travail si possible car votre code sera plus discret, plus configurable et plus Angulaire.

Si vous utilisez jQuery, vous ne devriez pas le répandre partout. Le bon endroit pour la manipulation DOM dans AngularJS est dans une directive. Plus sur ces derniers plus tard.

JavaScript discret avec sélecteurs vs modèles déclaratifs

jQuery est généralement appliqué discrètement. Votre code JavaScript est lié dans l'en-tête (ou le pied de page), et c'est le seul endroit où il est mentionné. Nous utilisons des sélecteurs pour sélectionner des parties de la page et écrire des plugins pour modifier ces parties.

Le JavaScript est en contrôle. Le HTML a une existence complètement indépendante. Votre HTML reste sémantique même sans JavaScript. Les attributs Onclick sont une très mauvaise pratique.

L'une des premières choses que vous remarquerez à propos d'AngularJS est que les attributs personnalisés sont partout . Votre HTML sera jonché d'attributs ng, qui sont essentiellement des attributs onClick sur les stéroïdes. Ce sont des directives (directives du compilateur), et sont l'une des principales façons dont le modèle est accroché au modèle.

Lorsque vous voyez cela pour la première fois, vous pourriez être tenté d'écrire AngularJS en tant que JavaScript intrusif de la vieille école (comme je l'ai fait au début). En fait, AngularJS ne respecte pas ces règles. Dans AngularJS, votre HTML5 est un modèle. Il est compilé par AngularJS pour produire votre page Web.

C'est la première grande différence. Pour jQuery, votre page web est un DOM à manipuler. Pour AngularJS, votre code HTML est du code à compiler. AngularJS lit dans votre page Web entière et la compile littéralement dans une nouvelle page Web en utilisant son compilateur intégré.

Votre modèle doit être déclaratif; sa signification doit être claire simplement en la lisant. Nous utilisons des attributs personnalisés avec des noms significatifs. Nous créons de nouveaux éléments HTML, toujours avec des noms significatifs. Un concepteur avec une connaissance HTML minimale et aucune compétence en codage peut lire votre modèle AngularJS et comprendre ce qu'il fait. Il ou elle peut apporter des modifications. C'est la voie angulaire.

Le gabarit est dans le siège conducteur.

L'une des premières questions que je me suis posée lors du démarrage d'AngularJS et de l'exécution des didacticiels est "Où est mon code?" . Je n'ai écrit aucun JavaScript, et pourtant j'ai tout ce comportement. La réponse est évidente. Comme AngularJS compile le DOM, AngularJS traite votre HTML comme du code. Pour de nombreux cas simples, il suffit souvent d'écrire un modèle et de laisser AngularJS le compiler dans une application pour vous.

Votre modèle pilote votre application. Il est traité comme une DSL . Vous écrivez des composants AngularJS, et AngularJS se chargera de les extraire et de les rendre disponibles au bon moment en fonction de la structure de votre modèle. C'est très différent d'un modèle MVC standard , où le modèle est juste pour la sortie.

Il est plus similaire à XSLT qu'à Ruby on Rails par exemple.

Il s'agit d'une inversion de contrôle radicale qui prend un certain temps pour s'y habituer.

Arrêtez d'essayer de piloter votre application à partir de votre JavaScript. Laissez le modèle piloter l'application et laissez AngularJS s'occuper du câblage des composants ensemble. C'est aussi la voie angulaire.

HTML sémantique vs modèles sémantiques

Avec jQuery, votre page HTML doit contenir un contenu significatif sémantique. Si le JavaScript est désactivé (par un utilisateur ou un moteur de recherche), votre contenu reste accessible.

Parce que AngularJS traite votre page HTML comme un modèle. Le modèle n'est pas censé être sémantique car votre contenu est généralement stocké dans votre modèle qui provient finalement de votre API. AngularJS compile votre DOM avec le modèle pour produire une page Web sémantique.

Votre source HTML n'est plus sémantique, au lieu de cela, votre API et DOM compilé sont sémantiques.

Dans AngularJS, ce qui signifie vit dans le modèle, le HTML est juste un modèle, pour l'affichage uniquement.

À ce stade, vous avez probablement toutes sortes de questions concernant le référencement et l'accessibilité, et à juste titre. Il y a des problèmes ouverts ici. La plupart des lecteurs d'écran analysent désormais JavaScript. Les moteurs de recherche peuvent également indexer le contenu AJAXed . Néanmoins, vous voudrez vous assurer que vous utilisez des URL pushstate et que vous avez un plan du site décent. Voir ici pour une discussion du problème: https://stackoverflow.com/a/23245379/687677

Séparation des préoccupations (SOC) vs MVC

La séparation des préoccupations (SOC) est un modèle qui a grandi au cours de nombreuses années de développement Web pour diverses raisons, notamment le référencement, l'accessibilité et l'incompatibilité du navigateur. Cela ressemble à ceci:

  1. HTML - Signification sémantique. Le HTML doit être autonome.
  2. CSS - Style, sans le CSS, la page est toujours lisible.
  3. JavaScript - Comportement, sans le script, le contenu reste.

Encore une fois, AngularJS ne respecte pas ses règles. D'un coup, AngularJS supprime une décennie de sagesse reçue et implémente à la place un modèle MVC dans lequel le modèle n'est plus sémantique, même pas un peu.

Cela ressemble à ceci:

  1. Modèle - vos modèles contiennent vos données sémantiques. Les modèles sont généralement des objets JSON . Les modèles existent en tant qu'attributs d'un objet appelé $ scope. Vous pouvez également stocker des fonctions utilitaires pratiques sur $ scope auxquelles vos modèles peuvent ensuite accéder.
  2. Vue - Vos vues sont écrites en HTML. La vue n'est généralement pas sémantique car vos données résident dans le modèle.
  3. Contrôleur - Votre contrôleur est une fonction JavaScript qui accroche la vue au modèle. Sa fonction est d'initialiser $ scope. Selon votre application, vous pouvez ou non avoir besoin de créer un contrôleur. Vous pouvez avoir plusieurs contrôleurs sur une page.

MVC et SOC ne sont pas aux extrémités opposées de la même échelle, ils sont sur des axes complètement différents. SOC n'a aucun sens dans un contexte AngularJS. Vous devez l'oublier et passer à autre chose.

Si, comme moi, vous avez vécu les guerres des navigateurs, vous pourriez trouver cette idée assez choquante. Dépassez-vous, ça vaudra le coup, je le promets.

Plugins vs directives

Les plugins étendent jQuery. Les directives AngularJS étendent les capacités de votre navigateur.

Dans jQuery, nous définissons les plugins en ajoutant des fonctions au jQuery.prototype. Nous les connectons ensuite au DOM en sélectionnant des éléments et en appelant le plugin sur le résultat. L'idée est d'étendre les capacités de jQuery.

Par exemple, si vous voulez un carrousel sur votre page, vous pouvez définir une liste non ordonnée de figures, peut-être enveloppée dans un élément nav. Vous pouvez ensuite écrire du jQuery pour sélectionner la liste sur la page et la redéfinir comme une galerie avec des délais d'attente pour faire l'animation glissante.

Dans AngularJS, nous définissons des directives. Une directive est une fonction qui renvoie un objet JSON. Cet objet indique à AngularJS quels éléments DOM rechercher et quels changements leur apporter. Les directives sont connectées au modèle à l'aide d'attributs ou d'éléments que vous inventez. L'idée est d'étendre les capacités du HTML avec de nouveaux attributs et éléments.

La méthode AngularJS consiste à étendre les capacités du HTML d'aspect natif. Vous devez écrire du HTML qui ressemble à du HTML, étendu avec des attributs et des éléments personnalisés.

Si vous voulez un carrousel, utilisez simplement un <carousel />élément, puis définissez une directive pour extraire un modèle et faire fonctionner cette ventouse.

Beaucoup de petites directives contre de gros plugins avec des commutateurs de configuration

La tendance avec jQuery est d'écrire de gros gros plugins comme lightbox que nous configurons ensuite en passant de nombreuses valeurs et options.

C'est une erreur dans AngularJS.

Prenons l'exemple d'une liste déroulante. Lors de l'écriture d'un plugin déroulant, vous pourriez être tenté de coder dans des gestionnaires de clics, peut-être une fonction pour ajouter un chevron qui est soit vers le haut soit vers le bas, peut-être changer la classe de l'élément déplié, afficher masquer le menu, toutes les choses utiles.

Jusqu'à ce que vous vouliez faire un petit changement.

Supposons que vous ayez un menu que vous souhaitez déplier en survol. Eh bien maintenant, nous avons un problème. Notre plugin a câblé notre gestionnaire de clics pour nous, nous allons devoir ajouter une option de configuration pour qu'il se comporte différemment dans ce cas spécifique.

Dans AngularJS, nous écrivons des directives plus petites. Notre directive déroulante serait ridiculement petite. Il peut conserver l'état plié et fournir des méthodes pour fold (), unfold () ou toggle (). Ces méthodes mettraient simplement à jour $ scope.menu.visible qui est un booléen contenant l'état.

Maintenant, dans notre modèle, nous pouvons câbler ceci:

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

Besoin de mettre à jour au survol de la souris?

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

Le modèle pilote l'application afin que nous obtenions une granularité de niveau HTML. Si nous voulons faire des exceptions au cas par cas, le modèle rend cela facile.

Clôture vs périmètre $

Les plugins JQuery sont créés dans une fermeture. La confidentialité est maintenue dans cette fermeture. C'est à vous de maintenir votre chaîne de portée dans cette fermeture. Vous n'avez vraiment accès qu'à l'ensemble des nœuds DOM transmis au plug-in par jQuery, ainsi qu'à toutes les variables locales définies dans la fermeture et à tous les globaux que vous avez définis. Cela signifie que les plugins sont assez autonomes. C'est une bonne chose, mais cela peut devenir restrictif lors de la création d'une application entière. Essayer de transmettre des données entre les sections d'une page dynamique devient une corvée.

AngularJS a des objets $ scope. Ce sont des objets spéciaux créés et maintenus par AngularJS dans lesquels vous stockez votre modèle. Certaines directives engendreront une nouvelle portée $ qui, par défaut, héritera de sa portée $ en utilisant l'héritage prototypique JavaScript. L'objet $ scope est accessible dans le contrôleur et la vue.

Ceci est la partie intelligente. Étant donné que la structure de l'héritage de $ scope suit à peu près la structure du DOM, les éléments ont accès à leur propre étendue et à toutes les étendues contenant de manière transparente, jusqu'à la portée globale de $ (qui n'est pas la même que la portée globale).

Cela facilite grandement la transmission des données et le stockage des données à un niveau approprié. Si une liste déroulante est dépliée, seule la portée $ dropdown doit en être informée. Si l'utilisateur met à jour ses préférences, vous souhaiterez peut-être mettre à jour la portée globale $, et toutes les étendues imbriquées écoutant les préférences de l'utilisateur seront automatiquement alertées.

Cela peut sembler compliqué, en fait, une fois que vous vous détendez, c'est comme voler. Vous n'avez pas besoin de créer l'objet $ scope, AngularJS l'instancie et le configure pour vous, correctement et de manière appropriée en fonction de votre hiérarchie de modèles. AngularJS le met ensuite à la disposition de votre composant en utilisant la magie de l'injection de dépendances (plus d'informations à ce sujet plus tard).

Modifications DOM manuelles et liaison de données

Dans jQuery, vous effectuez tous vos changements DOM à la main. Vous construisez de nouveaux éléments DOM par programmation. Si vous avez un tableau JSON et que vous souhaitez le mettre dans le DOM, vous devez écrire une fonction pour générer le HTML et l'insérer.

Dans AngularJS, vous pouvez également le faire, mais nous vous encourageons à utiliser la liaison de données. Modifiez votre modèle, et parce que le DOM y est lié via un modèle, votre DOM se mettra automatiquement à jour, aucune intervention requise.

Étant donné que la liaison de données est effectuée à partir du modèle, à l'aide d'un attribut ou de la syntaxe d'accolade, c'est très facile à faire. Il y a peu de frais généraux cognitifs associés, vous vous retrouverez donc à le faire tout le temps.

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

Lie l'élément d'entrée à $scope.user.name. La mise à jour de l'entrée mettra à jour la valeur dans votre portée actuelle, et vice-versa.

Également:

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

affichera le nom d'utilisateur dans un paragraphe. Il s'agit d'une liaison en direct, donc si la $scope.user.namevaleur est mise à jour, le modèle sera également mis à jour.

Ajax tout le temps

Dans jQuery, effectuer un appel Ajax est assez simple, mais c'est toujours quelque chose auquel vous pourriez penser à deux fois. Il y a la complexité supplémentaire à penser et une bonne partie de script à maintenir.

Dans AngularJS, Ajax est votre solution par défaut et cela se produit tout le temps, presque sans que vous ne le remarquiez. Vous pouvez inclure des modèles avec ng-include. Vous pouvez appliquer un modèle avec la directive personnalisée la plus simple. Vous pouvez encapsuler un appel Ajax dans un service et créer vous-même un service GitHub , ou un service Flickr , auquel vous pouvez accéder avec une facilité étonnante.

Objets de service vs fonctions d'assistance

Dans jQuery, si nous voulons accomplir une petite tâche non liée à dom comme extraire un flux d'une API, nous pouvons écrire une petite fonction pour le faire dans notre fermeture. C'est une solution valable, mais que se passe-t-il si nous voulons accéder souvent à ce flux? Et si nous voulons réutiliser ce code dans une autre application?

AngularJS nous donne des objets de service.

Les services sont des objets simples qui contiennent des fonctions et des données. Ce sont toujours des singletons, ce qui signifie qu'il ne peut jamais y en avoir plus d'un. Supposons que nous voulons accéder à l'API Stack Overflow, nous pourrions écrire un StackOverflowServicequi définit les méthodes pour le faire.

Disons que nous avons un panier d'achat. Nous pouvons définir un ShoppingCartService qui gère notre panier et contient des méthodes pour ajouter et supprimer des articles. Étant donné que le service est un singleton et qu'il est partagé par tous les autres composants, tout objet qui doit pouvoir écrire dans le panier et en extraire des données. C'est toujours le même chariot.

Les objets de service sont des composants AngularJS autonomes que nous pouvons utiliser et réutiliser comme bon nous semble. Ce sont de simples objets JSON contenant des fonctions et des données. Ce sont toujours des singletons, donc si vous stockez des données sur un service en un seul endroit, vous pouvez obtenir ces données ailleurs simplement en demandant le même service.

Injection de dépendance (DI) vs instatiation - alias dé-spaghettification

AngularJS gère vos dépendances pour vous. Si vous voulez un objet, référez-vous simplement à lui et AngularJS le trouvera pour vous.

Jusqu'à ce que vous commenciez à l'utiliser, il est difficile d'expliquer à quel point c'est une énorme bénédiction. Rien comme AngularJS DI n'existe dans jQuery.

DI signifie qu'au lieu d'écrire votre application et de la câbler ensemble, vous définissez plutôt une bibliothèque de composants, chacun identifié par une chaîne.

Disons que j'ai un composant appelé «FlickrService» qui définit les méthodes pour extraire les flux JSON de Flickr. Maintenant, si je veux écrire un contrôleur qui peut accéder à Flickr, il me suffit de faire référence au «FlickrService» par son nom lorsque je déclare le contrôleur. AngularJS se chargera d'instancier le composant et de le mettre à disposition de mon contrôleur.

Par exemple, ici je définis un service:

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

Maintenant, quand je veux utiliser ce service, je me réfère à lui par son nom comme ceci:

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

AngularJS reconnaîtra qu'un objet FlickrService est nécessaire pour instancier le contrôleur et nous en fournira un.

Cela rend le câblage des choses très facile et élimine à peu près toute tendance à la spagettification. Nous avons une liste plate de composants, et AngularJS nous les remet un par un au fur et à mesure de nos besoins.

Architecture de service modulaire

jQuery en dit très peu sur la façon dont vous devez organiser votre code. AngularJS a des opinions.

AngularJS vous propose des modules dans lesquels vous pouvez placer votre code. Si vous écrivez un script qui parle à Flickr par exemple, vous voudrez peut-être créer un module Flickr pour encapsuler toutes vos fonctions liées à Flickr. Les modules peuvent inclure d'autres modules (DI). Votre application principale est généralement un module, et cela devrait inclure tous les autres modules dont votre application dépendra.

Vous obtenez une réutilisation simple du code, si vous voulez écrire une autre application basée sur Flickr, vous pouvez simplement inclure le module Flickr et le tour est joué, vous avez accès à toutes vos fonctions liées à Flickr dans votre nouvelle application.

Les modules contiennent des composants AngularJS. Lorsque nous incluons un module, tous les composants de ce module deviennent disponibles pour nous comme une simple liste identifiée par leurs chaînes uniques . Nous pouvons ensuite injecter ces composants les uns dans les autres en utilisant le mécanisme d'injection de dépendance d'AngularJS.

Pour résumer

AngularJS et jQuery ne sont pas des ennemis. Il est possible d'utiliser jQuery dans AngularJS très bien. Si vous utilisez bien AngularJS (modèles, liaison de données, $ scope, directives, etc.), vous constaterez que vous avez besoin de beaucoup moins de jQuery que vous ne pourriez en avoir besoin autrement.

La principale chose à réaliser est que votre modèle pilote votre application. Arrêtez d'essayer d'écrire de gros plugins qui font tout. Au lieu de cela, écrivez de petites directives qui font une chose, puis écrivez un modèle simple pour les câbler ensemble.

Pensez moins au JavaScript discret et pensez plutôt aux extensions HTML.

Mon petit livre

Je suis tellement excité à propos d'AngularJS, j'ai écrit un court livre à ce sujet que vous êtes invités à lire en ligne http://nicholasjohnson.com/angular-book/ . J'espère que c'est utile.

superluminaire
la source
6
L'idée que «séparation des préoccupations» est différente de «MVC (modèle, vue, contrôleur)» est entièrement fausse. Le modèle des langages Web de séparation des préoccupations (HTML, CSS et JS) le fait en permettant aux gens de mettre des choses sur une page Web (le balisage / HTML) sans se soucier de son apparence (style / mise en page / CSS) ou de ce qu'elle "fait" (Événements DOM / AJAX / JavaScript). MVC sépare également les préoccupations. Chaque "couche" dans le modèle MVC a un rôle distinct - soit les données, le routage / la logique, soit le rendu. Les couches sont couplées par des rappels, des itinéraires et des liaisons de modèle. En théorie, une personne peut se spécialiser dans chaque couche, ce qui est souvent le cas.
En tant que personne issue d'un contexte SOC strict et défenseur de longue date des normes Web remontant aux guerres des navigateurs, j'ai d'abord trouvé les modèles non sémantiques et non validants d'Angular gênants. Je voulais juste préciser que pour écrire Angular, il faut abandonner le SOC tel qu'il est généralement pratiqué. Cela peut être une transition difficile.
superluminaire
Vous avez raison. SOC est un terme large, mais dans le monde du Web, SOC a (ou peut-être eu) une signification très spécifique: HTML sémantique, CSS de présentation et JavaScript pour le comportement. Je fais certaines hypothèses sur mon public qui ne sont peut-être pas raisonnables, je dois donc m'excuser également.
superluminaire du
Je trouve votre réponse la plus claire et la plus éclairante. Je suis un débutant ici, donc, si j'ai une extension pour changer une page existante (que je ne contrôle pas), dois-je garder JQuery alors?
Daniel Möller
152

Pouvez-vous décrire le changement de paradigme qui est nécessaire?

Impératif vs déclaratif

Avec jQuery, vous dites au DOM ce qui doit se produire, étape par étape. Avec AngularJS, vous décrivez les résultats que vous souhaitez, mais pas comment le faire. Plus à ce sujet ici . Consultez également la réponse de Mark Rajcok.

Comment puis-je concevoir et concevoir différemment des applications Web côté client?

AngularJS est un framework côté client complet qui utilise le modèle MVC (consultez leur représentation graphique ). Il met fortement l'accent sur la séparation des préoccupations.

Quelle est la plus grande différence? Que dois-je arrêter de faire / d'utiliser; que dois-je commencer à faire / utiliser à la place?

jQuery est une bibliothèque

AngularJS est un magnifique framework côté client, hautement testable, qui combine des tonnes de trucs sympas tels que MVC, l' injection de dépendances , la liaison de données et bien plus encore.

Il se concentre sur la séparation des préoccupations et les tests (tests unitaires et tests de bout en bout), ce qui facilite le développement piloté par les tests.

La meilleure façon de commencer est de parcourir leur formidable tutoriel . Vous pouvez suivre les étapes en quelques heures; cependant, si vous souhaitez maîtriser les concepts en coulisses, ils incluent une myriade de références pour une lecture plus approfondie.

Y a-t-il des considérations / restrictions côté serveur?

Vous pouvez l'utiliser sur des applications existantes où vous utilisez déjà pure jQuery. Cependant, si vous souhaitez profiter pleinement des fonctionnalités AngularJS, vous pouvez envisager de coder côté serveur à l'aide d'une approche RESTful .

Cela vous permettra de tirer parti de leur fabrique de ressources , ce qui crée une abstraction de votre API RESTful côté serveur et rend les appels côté serveur (obtenir, enregistrer, supprimer, etc.) incroyablement faciles.

Ulises
la source
27
Je pense que vous embrouillez les eaux en parlant de la façon dont jQuery est une "bibliothèque" et Angular est un "framework" ... pour une chose, je pense qu'il est possible de faire valoir que jQuery est un framework ... c'est une abstraction de la manipulation DOM et de la gestion des événements. Ce n'est peut-être pas un cadre pour le même genre de chose qu'Angular, mais c'est le dilemme dans lequel se trouve le poseur de questions: ils ne connaissent pas vraiment la différence entre Angular et jQuery, et pour tout le questionneur le sait, jQuery est un cadre pour la création de sites Web clients lourds. Donc, discuter de la terminologie ne clarifiera pas les choses.
Zando
15
Je pense que vous êtes celui qui devient confus. Cette question concerne exactement ce stackoverflow.com/questions/7062775 . En outre, cette réponse peut aider à clarifier la différence entre un framework et une bibliothèque: stackoverflow.com/a/148759/620448
Ulises
6
Une bibliothèque ne devient pas un "framework" simplement parce que sa collection de fonctions est particulièrement utile ou volumineuse. Un cadre prend des décisions pour vous. Lorsque vous commencez à utiliser AngularJS, vous êtes susceptible de vous y coupler par sa nature. (Ex: vous ne devriez mettre à jour le DOM que dans les directives, sinon quelque chose va gâcher.) C'est parce que AngularJS est un framework. Lorsque vous utilisez jQuery, vous pouvez mélanger et assortir des outils relativement facilement avec un risque de conflit minimal. C'est parce que jQuery est une bibliothèque, et au moins à moitié décente aussi.
8
Une bibliothèque est un code que vous appelez. Un framework est du code qui appelle votre code. Par cette définition, Angular est un cadre. Vous lui fournissez des composants et Angular veille à ce que vos composants soient instanciés avec les dépendances dont ils ont besoin.
superluminaire
84

Pour décrire le "changement de paradigme", je pense qu'une réponse courte peut suffire.

AngularJS change la façon dont vous trouvez les éléments

Dans jQuery , vous utilisez généralement des sélecteurs pour rechercher des éléments, puis les câblez:
$('#id .class').click(doStuff);

Dans AngularJS , vous utilisez des directives pour marquer directement les éléments, pour les câbler:
<a ng-click="doStuff()">

AngularJS n'a pas besoin (ou veulent) que vous trouverez des éléments à l' aide de sélecteurs - la principale différence entre AngularJS de jqLite par rapport complet jQuery est que jqLite ne supporte pas les sélecteurs .

Donc, quand les gens disent "n'inclut pas du tout jQuery", c'est principalement parce qu'ils ne veulent pas que vous utilisiez des sélecteurs; ils veulent que vous appreniez à utiliser des directives à la place. Direct, pas sélectionner!

Scott Rippey
la source
13
Juste comme un avertissement, il y a BEAUCOUP plus de différences majeures entre Angular et jQuery. Mais trouver des éléments est celui qui nécessite le plus grand changement de pensée.
Scott Rippey
1
pardonnez-moi si je me trompe, mais je pensais qu'un sélecteur était ce que vous utilisez pour trouver l'élément DOM? Vous préférez garder chaque partie de votre interface utilisateur nouvellement chargée en référence, plutôt que de simplement sélectionner le ou les 2 éléments sur lesquels un utilisateur peut cliquer, à la volée à l'aide d'un sélecteur? sonne plus dur pour moi ..
RozzA
3
@AlexanderPritchard Le point angulaire est que vous ne sélectionnez pas à partir de votre JavaScript, vous dirigez à partir de votre modèle. C'est une inversion de contrôle qui met le pouvoir entre les mains du designer. Il s'agit d'un principe de conception délibéré. Pour vraiment obtenir Angular, vous devez penser à votre code de cette façon. C'est un changement difficile à faire.
superluminaire
3
@superluminary Quelle belle citation! "ne sélectionnez pas, dirigez!" Sérieusement, je vais l'utiliser.
Scott Rippey
1
C'est l'une de mes choses préférées à propos d'AngularJS. Je n'ai pas à m'inquiéter du fait que l'équipe UX casse mes fonctionnalités ou que je casse leurs styles. Ils utilisent des classes, j'utilise des directives, point. Je ne manque aucun bit de sélecteurs.
adam0101
69

jQuery

jQuery crée des commandes JavaScript ridiculement longues comme getElementByHerpDerpdes navigateurs plus courts et croisés.

AngularJS

AngularJS vous permet de créer vos propres balises / attributs HTML qui font des choses qui fonctionnent bien avec les applications Web dynamiques (puisque HTML a été conçu pour les pages statiques).

Éditer:

Dire "J'ai un arrière-plan jQuery, comment puis-je penser dans AngularJS?" c'est comme dire "J'ai un fond HTML comment penser en JavaScript?" Le fait que vous posiez la question montre que vous ne comprenez probablement pas les objectifs fondamentaux de ces deux ressources. C'est pourquoi j'ai choisi de répondre à la question en soulignant simplement la différence fondamentale plutôt que de parcourir la liste en disant "AngularJS utilise des directives alors que jQuery utilise des sélecteurs CSS pour créer un objet jQuery qui fait ceci et cela etc ...." . Cette question ne nécessite pas de réponse longue.

jQuery est un moyen de faciliter la programmation de JavaScript dans le navigateur. Commandes plus courtes et inter-navigateurs, etc.

AngularJS étend le HTML, vous n'avez donc pas à <div>tout mettre juste pour faire une application. Cela fait que le HTML fonctionne réellement pour les applications plutôt que pour ce pour quoi il a été conçu, à savoir des pages Web éducatives statiques. Il accomplit cela de manière détournée en utilisant JavaScript, mais fondamentalement, c'est une extension de HTML, pas de JavaScript.

Nick Manning
la source
@Robert dépend de ce que vous faites. $(".myclass")est extrêmement courant et plus facile dans jQuery que PO-Javascript.
Rob Grant du
61

jQuery: vous pensez beaucoup à "QUERYing the DOM " pour les éléments DOM et à faire quelque chose.

AngularJS: LE modèle est la vérité, et vous pensez toujours de cet ANGLE.

Par exemple, lorsque vous obtenez des données du serveur que vous avez l'intention d'afficher dans un certain format dans le DOM, dans jQuery, vous devez '1. TROUVEZ 'où dans le DOM vous souhaitez placer ces données, le' 2. METTRE À JOUR / AJOUTER là-bas en créant un nouveau nœud ou en définissant simplement son innerHTML . Ensuite, lorsque vous souhaitez mettre à jour cette vue, vous avez alors '3. TROUVEZ «l'emplacement» et «4. MISE À JOUR'. Ce cycle de recherche et de mise à jour effectué dans le même contexte d'obtention et de formatage des données du serveur a disparu dans AngularJS.

Avec AngularJS, vous avez votre modèle (les objets JavaScript auxquels vous êtes déjà habitué) et la valeur du modèle vous informe sur le modèle (évidemment) et sur la vue, et une opération sur le modèle se propage automatiquement à la vue, donc vous ne le faites pas '' t y penser. Vous vous retrouverez dans AngularJS ne trouvant plus de choses dans le DOM.

En d'autres termes, dans jQuery, vous devez penser aux sélecteurs CSS, c'est-à-dire où est le divou tdqui a une classe ou un attribut, etc., afin que je puisse obtenir leur HTML ou leur couleur ou leur valeur, mais dans AngularJS, vous vous retrouverez à penser comme ceci: avec quel modèle ai-je affaire, je définirai la valeur du modèle sur vrai. Vous ne vous souciez pas de savoir si la vue reflétant cette valeur est une case cochée ou réside dans un tdélément (des détails auxquels vous auriez souvent dû penser dans jQuery).

Et avec la manipulation DOM dans AngularJS, vous vous retrouvez à ajouter des directives et des filtres, que vous pouvez considérer comme des extensions HTML valides.

Une autre chose que vous rencontrerez dans AngularJS: dans jQuery vous appelez beaucoup les fonctions jQuery, dans AngularJS, AngularJS appellera vos fonctions, donc AngularJS vous 'dira comment faire les choses', mais les avantages en valent la peine, donc apprendre AngularJS signifie généralement apprendre ce que veut AngularJS ou la façon dont AngularJS exige que vous présentiez vos fonctions et il l'appellera en conséquence. C'est l'une des choses qui fait d'AngularJS un framework plutôt qu'une bibliothèque.

Samuel
la source
46

Ce sont des réponses très agréables mais longues.

Pour résumer mes expériences:

  1. Les contrôleurs et les fournisseurs (services, usines, etc.) sont chargés de modifier le modèle de données, PAS HTML.
  2. Le HTML et les directives définissent la disposition et la liaison au modèle.
  3. Si vous avez besoin de partager des données entre des contrôleurs, créez un service ou une usine - ce sont des singletons qui sont partagés à travers l'application.
  4. Si vous avez besoin d'un widget HTML, créez une directive.
  5. Si vous avez des données et que vous essayez maintenant de mettre à jour le HTML ... STOP! mettez à jour le modèle et assurez-vous que votre code HTML est lié au modèle.
Dan
la source
45

jQuery est une bibliothèque de manipulation DOM.

AngularJS est un framework MV *.

En fait, AngularJS est l'un des rares frameworks JavaScript MV * (de nombreux outils JavaScript MVC relèvent toujours de la bibliothèque de catégories).

En tant que framework, il héberge votre code et prend en charge les décisions concernant les appels et les dates!

AngularJS lui-même comprend une édition jQuery-lite en son sein. Donc, pour une sélection / manipulation DOM de base, vous n'avez vraiment pas besoin d'inclure la bibliothèque jQuery (elle économise de nombreux octets à exécuter sur le réseau.)

AngularJS a le concept de "directives" pour la manipulation DOM et la conception de composants d'interface utilisateur réutilisables, vous devez donc l'utiliser chaque fois que vous ressentez le besoin de faire des choses liées à la manipulation DOM (les directives ne sont que des endroits où vous devez écrire du code jQuery tout en utilisant AngularJS).

AngularJS implique une courbe d'apprentissage (plus que jQuery :-).

-> Pour tout développeur issu du milieu jQuery, mon premier conseil serait "d'apprendre JavaScript en tant que langage de première classe avant de sauter sur un framework riche comme AngularJS!" J'ai appris le fait ci-dessus à la dure.

Bonne chance.

Anand
la source
34

Ce sont des pommes et des oranges. Vous ne voulez pas les comparer. Ce sont deux choses différentes. AngularJs a déjà intégré jQuery Lite qui vous permet d'effectuer une manipulation DOM de base sans même inclure la version complète de jQuery.

jQuery concerne la manipulation DOM. Il résout toute la douleur entre les navigateurs, sinon vous devrez faire face, mais ce n'est pas un cadre qui vous permet de diviser votre application en composants comme AngularJS.

Une bonne chose à propos d'AngularJs est qu'il vous permet de séparer / isoler la manipulation DOM dans les directives. Il existe des directives intégrées prêtes à l'emploi, telles que ng-click. Vous pouvez créer vos propres directives personnalisées qui contiendront toute votre logique de vue ou toute manipulation DOM afin de ne pas finir par mélanger du code de manipulation DOM dans les contrôleurs ou les services qui devraient prendre en charge la logique métier.

Angular décompose votre application en - Contrôleurs - Services - Vues - etc.

et il y a encore une chose, c'est la directive. C'est un attribut que vous pouvez attacher à n'importe quel élément DOM et vous pouvez devenir fou avec jQuery en lui sans vous soucier des conflits entre jQuery et les composants AngularJs ou gâcher son architecture.

J'ai entendu parler d'une rencontre à laquelle j'ai assisté, l'un des fondateurs d'Angular a déclaré qu'ils avaient travaillé très dur pour séparer la manipulation du DOM, alors n'essayez pas de les réintégrer.

Jin
la source
31

Écoutez le podcast JavaScript Jabber: Episode # 32 qui présente les créateurs originaux d'AngularJS: Misko Hevery & Igor Minar. Ils parlent beaucoup de ce que c'est que de venir à AngularJS à partir d'autres arrière-plans JavaScript, en particulier jQuery.

Un des points soulevés dans le podcast a fait claquer beaucoup de choses en ce qui concerne votre question:

MISKO : [...] l'une des choses auxquelles nous avons très difficilement pensé dans Angular est, comment pouvons-nous fournir beaucoup de trappes d'évacuation pour que vous puissiez sortir et trouver un moyen de sortir de cela. Donc, pour nous, la réponse est cette chose appelée «directives». Et avec les directives, vous devenez essentiellement un petit JavaScript jQuery régulier, vous pouvez faire ce que vous voulez.

IGOR : Considérez donc la directive comme l'instruction du compilateur qui l'indique chaque fois que vous rencontrez cet élément ou ce CSS dans le modèle, et vous gardez ce type de code et ce code est en charge de l'élément et de tout ce qui se trouve en dessous de cet élément dans l'arborescence DOM.

Une transcription de l'épisode entier est disponible sur le lien fourni ci-dessus.

Donc, pour répondre directement à votre question: AngularJS est très avisé et est un véritable framework MV *. Cependant, vous pouvez toujours faire toutes les choses vraiment cool que vous connaissez et aimez avec jQuery dans les directives. Il ne s'agit pas de "Comment faire ce que j'avais l'habitude de faire dans jQuery?" autant que c'est une question de "Comment puis-je compléter AngularJS avec tout ce que je faisais dans jQuery?"

C'est vraiment deux états d'esprit très différents.

codevinsky
la source
2
Je ne suis pas sûr que je serais tout à fait d'accord Angular est TRÈS opiniâtre. Vous voulez une opinion, regardez Ember. Je présenterais Angular comme ayant des opinions sur les bouchons d'or - pour beaucoup de ce que je vois, jQuery a trop peu d'opinions et Ember en a trop. Les angulaires semblent parfaits.
fool4jesus
30

Je trouve cette question intéressante, car ma première exposition sérieuse à la programmation JavaScript a été Node.js et AngularJS. Je n'ai jamais appris jQuery, et je suppose que c'est une bonne chose, car je n'ai rien à désapprendre. En fait, j'évite activement les solutions jQuery à mes problèmes, et au lieu de cela, je cherche uniquement un "moyen AngularJS" pour les résoudre. Donc, je suppose que ma réponse à cette question se résumerait essentiellement à "penser comme quelqu'un qui n'a jamais appris jQuery" et éviter toute tentation d'incorporer directement jQuery (évidemment AngularJS l'utilise dans une certaine mesure en coulisses).

Evan Zamir
la source
23

AngularJS et jQuery:

AngularJs et JQuery sont complètement différents à tous les niveaux sauf la fonctionnalité JQLite et vous le verrez une fois que vous commencerez à apprendre les fonctionnalités principales d'AngularJs (je l'ai expliqué ci-dessous).

AngularJs est un framework côté client qui propose de construire l'application indépendante côté client. JQuery est une bibliothèque côté client qui joue autour du DOM.

AngularJs Cool Principle - Si vous souhaitez apporter des modifications à votre interface utilisateur, pensez du point de vue du changement des données du modèle. Modifiez vos données et l'interface utilisateur s'affichera de nouveau. Vous n'avez pas besoin de jouer autour de DOM à chaque fois, sauf si et jusqu'à ce qu'il soit à peine nécessaire et cela devrait également être géré par le biais de directives angulaires.

Pour répondre à cette question, je souhaite partager mon expérience sur la première application d'entreprise avec AngularJS. Ce sont les fonctionnalités les plus impressionnantes qu'Angular offre lorsque nous commençons à changer notre état d'esprit jQuery et que nous obtenons Angular comme un cadre et non la bibliothèque.

La liaison de données bidirectionnelle est incroyable: j'avais une grille avec toutes les fonctionnalités UPDATE, DELTE, INSERT. J'ai un objet de données qui lie le modèle de la grille à l'aide de ng-repeat. Vous n'avez qu'à écrire une seule ligne de code JavaScript simple pour supprimer et insérer et c'est tout. la grille est automatiquement mise à jour lorsque le modèle de grille change instantanément. La fonctionnalité de mise à jour est en temps réel, pas de code pour cela. Vous vous sentez incroyable !!!

Les directives réutilisables sont super: écrivez des directives en un seul endroit et utilisez-les tout au long de l'application. OMG!!! J'ai utilisé ces directives pour la pagination, l'expression régulière, les validations, etc. C'est vraiment cool!

Le routage est solide: c'est à votre implémentation comment vous souhaitez l'utiliser, mais il nécessite très peu de lignes de code pour acheminer la demande afin de spécifier HTML et contrôleur (JavaScript)

Les contrôleurs sont excellents: les contrôleurs prennent soin de leur propre code HTML, mais cette séparation fonctionne bien pour les fonctionnalités courantes. Si vous voulez appeler la même fonction sur le clic d'un bouton sur le HTML principal, écrivez simplement le même nom de fonction dans chaque contrôleur et écrivez le code individuel.

Plugins: Il existe de nombreuses autres fonctionnalités similaires, telles que l'affichage d'une superposition dans votre application. Vous n'avez pas besoin d'écrire de code pour cela, utilisez simplement un plugin de superposition disponible en wc-superposition, et cela prendra automatiquement en charge toutes les requêtes XMLHttpRequest (XHR).

Idéal pour l' architecture RESTful : Être un framework complet rend AngularJS idéal pour travailler avec une architecture RESTful. Appeler les API REST CRUD est très simple et

Services : Écrivez des codes communs en utilisant des services et moins de code dans les contrôleurs. Les services peuvent être utilisés pour partager des fonctionnalités communes entre les contrôleurs.

Extensibilité : Angular a étendu les directives HTML en utilisant des directives angulaires. Écrivez des expressions dans html et évaluez-les lors de l'exécution. Créez vos propres directives et services et utilisez-les dans un autre projet sans effort supplémentaire.

Sanjeev Singh
la source
20

En tant que débutant JavaScript MV * et se concentrant uniquement sur l'architecture de l'application (pas sur les questions côté serveur / client), je recommanderais certainement la ressource suivante (qui, je m'étonne, n'a pas encore été mentionnée): JavaScript Design Patterns , par Addy Osmani , comme introduction aux différents modèles de conception JavaScript . Les termes utilisés dans cette réponse sont tirés du document lié ci-dessus. Je ne vais pas répéter ce qui a été très bien formulé dans la réponse acceptée. Au lieu de cela, cette réponse renvoie aux arrière- plans théoriques qui alimentent AngularJS (et d'autres bibliothèques).

Comme moi, vous vous rendrez rapidement compte que AngularJS (ou Ember.js , Durandal et d'autres frameworks MV * d'ailleurs) est un framework complexe assemblant de nombreux modèles de conception JavaScript différents.

J'ai également trouvé plus facile de tester (1) du code JavaScript natif et (2) des bibliothèques plus petites pour chacun de ces modèles séparément avant de plonger dans un cadre global. Cela m'a permis de mieux comprendre à quels problèmes cruciaux un framework répond (car vous êtes personnellement confronté au problème).

Par exemple:

  • Programmation orientée objet JavaScript (il s'agit d'un lien de recherche Google). Ce n'est pas une bibliothèque, mais certainement une condition préalable à toute programmation d'application. Il m'a appris les implémentations natives des modèles de prototype, constructeur, singleton et décorateur
  • jQuery / Underscore pour le motif de la façade (comme WYSIWYG pour la manipulation du DOM)
  • Prototype.js pour le modèle prototype / constructeur / mixin
  • RequireJS / Curl.js pour le modèle de module / AMD
  • KnockoutJS pour le modèle observable de publication / abonnement

NB: Cette liste n'est pas complète, ni «les meilleures bibliothèques»; ce sont juste les bibliothèques que j'ai utilisées. Ces bibliothèques incluent également plus de modèles, ceux mentionnés ne sont que leurs principaux objectifs ou intentions originales. Si vous sentez que quelque chose manque dans cette liste, veuillez le mentionner dans les commentaires, et je serai heureux de l'ajouter.

Tyblitz
la source
12

En fait, si vous utilisez AngularJS, vous n'avez plus besoin de jQuery. AngularJS lui-même a la liaison et la directive, qui est un très bon "remplacement" pour la plupart des choses que vous pouvez faire avec jQuery.

Je développe généralement des applications mobiles en utilisant AngularJS et Cordova . La seule chose dont j'avais besoin de jQuery est le sélecteur.

En recherchant sur Google, je constate qu'il existe un module de sélection jQuery autonome. C'est Sizzle.

Et j'ai décidé de faire un petit extrait de code qui m'aide à démarrer rapidement un site Web en utilisant AngularJS avec la puissance de jQuery Selector (en utilisant Sizzle).

J'ai partagé mon code ici: https://github.com/huytd/Sizzular

Huy Tran
la source