Question "Penser en AngularJS" si j'ai un background jQuery? [fermé]


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

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

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


4525
2018-02-21 04:09


origine


Réponses:


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

Dans jQuery, vous concevez une page, puis vous la rendez dynamique. C'est parce que jQuery a été conçu pour l'augmentation et a grandi incroyablement de cette simple prémisse.

Mais dans AngularJS, vous devez partir de zéro avec votre architecture en tête. Au lieu de commencer par penser "J'ai cette partie du DOM et je veux la faire faire X", vous devez commencer par ce que vous voulez accomplir, puis allez sur la conception de votre application, puis enfin concevoir votre point de 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 de cela pour les modèles et les contrôleurs. C'est vraiment C'est tentant quand vous débutez, c'est pourquoi je recommande toujours que les nouveaux développeurs d'AngularJS n'utilisent pas du tout jQuery, du moins jusqu'à ce qu'ils s'habituent à faire des choses comme "Angular Way".

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 $applys qui sont confus et alambiqué; mais ils finissent par le faire fonctionner! Le problème est que dans plus cas où jQuery plugin 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 "penser en AngularJS"; si vous ne pouvez pas penser à une solution, demandez à la communauté; si après tout cela il n'y a pas de solution facile, puis n'hésitez pas à atteindre pour le jQuery. Mais ne laissez pas jQuery devenir une béquille ou vous ne maîtriserez jamais AngularJS.

3. Pensez toujours en termes d'architecture

D'abord savoir que applications d'une seule page sont applications. Ils sont ne pas les pages Web. Nous devons donc penser comme un développeur côté serveur en outre à 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.

Donc alors Comment faites-vous cela? Comment "pensez-vous en AngularJS"? Voici quelques principes généraux, contrastés avec jQuery.

La vue est le "record officiel"

En jQuery, nous changeons la vue par programme. Nous pourrions avoir un menu déroulant défini comme ul ainsi:

<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'activions avec quelque chose comme:

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

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

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

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

Ces deux font la même chose, mais dans la version AngularJS, quiconque regarde le template sait ce qui est supposé arriver. Chaque fois qu'un nouveau membre de l'équipe de développement vient à bord, elle peut regarder cela, puis connaître qu'il y a une directive appelée dropdownMenu opérer dessus; elle n'a pas besoin de deviner la bonne réponse ou de passer en revue n'importe quel code. La vue nous a dit ce qui était censé arriver. Beaucoup plus propre.

Les développeurs qui ne connaissent pas AngularJS posent souvent une question comme: comment puis-je trouver tous les liens d'un type spécifique et y ajouter une directive? Le développeur est toujours abasourdi quand nous répondons: ce n'est pas le cas. Mais la raison pour laquelle vous ne faites pas cela est que c'est comme demi-jQuery, moitié-AngularJS, et pas bon. Le problème ici est que le développeur essaie de "faire jQuery" dans le contexte de AngularJS. Cela ne marchera jamais bien. La vue est le dossier officiel. En dehors d'une directive (plus sur ce point ci-dessous), jamais, jamais, jamais change le DOM. Et les directives sont appliquées dans la vue, donc l'intention est claire.

Rappelez-vous: ne concevez pas, puis marquez. Vous devez architecte, puis concevoir.

Liaison de données

C'est de loin l'une des caractéristiques les plus impressionnantes d'AngularJS et élimine beaucoup le besoin de faire les types de manipulations DOM que j'ai mentionnés 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>

En plus de mélanger les préoccupations, nous avons également les mêmes problèmes d'intention signifiante que j'ai déjà mentionnés. Mais plus important encore, nous devions référencer et mettre à jour manuellement un noeud DOM. Et si nous voulons supprimer une entrée de journal, nous devons aussi coder avec le DOM pour cela. Comment testons-nous la logique en dehors du DOM? Et si nous voulons changer la présentation?

C'est un peu brouillon et un peu frêle. Mais dans AngularJS, nous pouvons faire ceci:

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

Et notre 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  ou Comment le journal est mis à jour, la vue change aussi. Automatiquement Soigné!

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

Couche de modèle distincte

En jQuery, le DOM est un peu comme le modèle. Mais dans AngularJS, nous avons une couche de modèle séparée que nous pouvons gérer comme bon nous semble, indépendamment de la vue. Cela aide pour la liaison de données ci-dessus, maintient séparation des préoccupationset introduit une testabilité beaucoup plus grande. D'autres réponses ont mentionné ce point, alors je vais m'en tenir à cela.

Séparation des préoccupations

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

Injection de dépendance

Pour nous aider à la séparation des préoccupations est injection de dépendance (DI). Si vous venez d'un langage côté serveur (de Java à PHP) vous connaissez probablement déjà ce concept, mais si vous êtes un client du côté de jQuery, ce concept peut sembler quelque chose de stupide à 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 et ensuite à partir de n'importe quel autre composant, demandez simplement une instance de celui-ci et il sera accordé. Vous n'avez pas besoin de connaître l'ordre de chargement, l'emplacement des fichiers ou quoi que ce soit de ce genre. La puissance peut ne pas être immédiatement visible, mais je ne donnerai qu'un exemple (commun): le test.

Disons que dans notre application, nous avons besoin d'un service qui implémente le stockage côté serveur à travers un DU REPOS API et, en fonction de l'état de l'application, du stockage local. Lorsque vous exécutez des tests sur nos contrôleurs, nous ne voulons pas avoir à communiquer avec le serveur. Nous testons manette, après tout. Nous pouvons simplement ajouter un service simulé du même nom que notre composant d'origine, et l'injecteur veillera à ce que notre contrôleur obtienne automatiquement le faux - notre contrôleur n'a pas et n'a pas besoin de connaître 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 comme sa propre section de haut niveau.

Parmi 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 très nombreux car jQuery n'est pas très accessible à ça. Mais AngularJS est.

Dans jQuery, la seule façon de tester est souvent de créer le composant de manière indépendante avec une page d'exemple / démo par rapport à laquelle nos tests peuvent effectuer une manipulation DOM. Alors nous devons développer un composant séparément et puis l'intégrer dans notre application. Quel inconvénient! La plupart du temps, lorsque nous développons avec jQuery, nous optons pour un développement itératif plutôt que provoqué par les tests. Et qui pourrait nous blâmer?

Mais parce que nous avons une séparation des préoccupations, nous pouvons faire un 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 dans la vue de notre application:

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

D'accord, maintenant nous pouvons écrire un test pour l'inexistant when-active directif:

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

Et lorsque nous effectuons notre test, nous pouvons confirmer qu'il échoue. Seulement maintenant devrions-nous 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 tous les deux itératif et piloté par les tests. Wicked-cool.

5. Conceptuellement, les directives sont ne pas jQuery emballé

Vous entendrez souvent "ne manipuler le DOM que dans une directive". C'est une nécessité. Traitez-le avec la déférence due!

Mais plongons un peu plus profond ...

Certaines directives décorent simplement ce qui est déjà dans la vue (pensez ngClass) et donc parfois faire des manipulations DOM tout de suite et puis sont essentiellement fait. Mais si une directive est comme un "widget" et a un modèle, il devrait aussi respecter la séparation des préoccupations. C'est le modèle aussi devrait rester largement indépendant de sa mise en œuvre dans les fonctions de liaison et de contrôleur.

AngularJS est livré avec un ensemble d'outils pour rendre cela très facile; avec ngClass nous pouvons mettre à jour dynamiquement la classe; ngModel permet une liaison de données bidirectionnelle; ngShow et ngHide afficher ou masquer par programme un élément; et beaucoup plus - y compris ceux que nous écrivons nous-mêmes. En d'autres termes, nous pouvons faire toutes sortes de génialité sans pour autant Manipulation DOM. Moins il y a de manipulation DOM, plus il est facile de tester les directives, plus elles sont faciles à coiffer, plus elles sont faciles à changer dans le futur et plus elles sont réutilisables et distribuables.

Je vois beaucoup de développeurs qui ne connaissent pas AngularJS en utilisant des directives comme l'endroit où 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 le mettre dans une directive". Alors que c'est certainement beaucoup mieux, c'est souvent toujours incorrecte.

Pensez à l'enregistreur que nous avons programmé dans la section 3. Même si nous mettons cela dans une directive, nous encore vouloir le faire la "Voie Angulaire". Il encore ne prend aucune manipulation DOM! Il y a beaucoup de fois où la manipulation DOM est nécessaire, mais c'est un lot plus rare que vous ne le pensez! Avant de manipuler le DOM nulle part Dans votre demande, demandez-vous si vous en avez vraiment besoin. Il pourrait y avoir un meilleur moyen.

Voici un exemple rapide qui montre le motif que je vois le plus souvent. Nous voulons un bouton toggleable. (Note: cet exemple est un peu artificiel et un skosh verbeux pour représenter des cas plus complexes 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 ceci:

  1. D'abord, jQuery n'a jamais été nécessaire. Il n'y a rien que nous ayons fait ici qui ait eu besoin de jQuery!
  2. Deuxièmement, même si nous avons déjà jQuery sur notre page, il n'y a aucune raison de l'utiliser ici; nous pouvons simplement utiliser angular.element et notre composant fonctionnera quand il tombera 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) volonté toujours utilisez 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ée à la troisième, est que les éléments jqLite ne doivent pas être enveloppés dans $ - la element qui est passé à la link fonction serait être déjà un élément jQuery!
  5. Et cinquièmement, que nous avons mentionné dans les sections précédentes, pourquoi mélangeons-nous des modèles 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, de sorte que vous (ou vos utilisateurs) pouvez facilement l'échanger pour un qui répond à tout style nécessaire, et le logique n'a jamais eu à être touché. Réutilisable - 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, ce qui facilite le refactoring. Vous pouvez modifier le modèle autant que vous le souhaitez sans toucher à la directive. Et peu importe ce que vous changez, vos tests passent toujours.

w00t!

Donc, si les directives ne sont pas seulement des collections de fonctions similaires à jQuery, de quoi s'agit-il? Les directives sont en fait extensions de HTML. Si le HTML ne fait pas quelque chose que vous avez besoin de faire, vous écrivez une directive pour le faire pour vous, et ensuite l'utiliser comme s'il faisait partie du HTML.

Autrement dit, si AngularJS ne fait pas quelque chose hors de la boîte, pensez à la façon dont l'équipe l'accomplira pour s'adapter ngClick, ngClass, et al.

Résumé

N'utilisez même pas jQuery. Ne l'incluez même pas. Cela vous retiendra. Et quand vous arrivez à un problème que vous pensez savoir résoudre dans jQuery déjà, avant d'atteindre le $, essayez de penser à 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 donne plus de travail pour vous.


7187
2018-02-21 21:26



Impératif → déclaratif

En jQuery, sélecteurs sont utilisés pour trouver DOM éléments et ensuite lier / enregistrer les gestionnaires d'événements à eux. 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 à vues plutôt que des éléments DOM. Les vues sont des HTML (déclaratifs) qui contiennent AngularJS directives. Les directives mettent en place les gestionnaires d'événements dans les coulisses et nous fournissent 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 grandement diminué. Les vues sont liées à des modèles (via des portées). Les vues sont une projection du modèle. Les événements changent les modèles (c'est-à-dire, les données, les propriétés de la portée) et les vues qui projettent ces modèles se mettent à 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 emploie JavaScript discret - le comportement (JavaScript) est séparé de la structure (HTML).

AngularJS utilise contrôleurs et les directives (dont chacune peut avoir son propre contrôleur, et / ou ses fonctions de compilation et de liaison) pour supprimer le comportement de la vue / structure (HTML). Angulaire a aussi prestations de service et filtres pour 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. Pensez à la façon dont vous voulez présenter vos modèles - vos points de vue. 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 routing, 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 minces 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 prototype / prototypique dans AngularJS?


408
2018-02-21 04:09



AngularJS contre jQuery

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

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

La grande différence (TLDR)

jQuery vous fournit une boîte à outils pour sélectionner des bits arbitraires du DOM et y apporter des modifications ad-hoc. Vous pouvez faire à peu près tout ce que vous voulez, pièce par pièce.

AngularJS vous donne plutôt un compilateur.

Ce que cela signifie est que AngularJS lit votre DOM entier de haut en bas et le traite comme du code, littéralement comme des instructions pour le compilateur. Comme il traverse le DOM, il cherche spécifique directives (directives du compilateur) qui indiquent au compilateur AngularJS comment se comporter et quoi faire. Les directives sont de petits objets remplis de JavaScript qui peuvent correspondre à des attributs, des balises, des classes ou même des commentaires.

Lorsque le compilateur angulaire détermine qu'une partie du DOM correspond à une directive particulière, il appelle la fonction directive, lui passant l'élément DOM, tous les attributs, le $ $ scope actuel (qui est un magasin de variables locales) 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 rendre et quand il doit se redessiner.

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

Cela signifie que Angular est basé sur un modèle. Votre modèle pilote le JavaScript, pas l'inverse. C'est un renversement radical des rôles, et le contraire du JavaScript discret que nous avons écrit pendant les 10 dernières années. Cela peut prendre un certain temps pour s'y habituer.

Si cela semble être trop prescriptif et limitant, rien ne pourrait être plus éloigné de la vérité. Parce que AngularJS traite votre code HTML comme du code, vous obtenez Granularité au niveau HTML dans votre application Web. Tout est possible, et la plupart des choses sont étonnamment faciles une fois que vous faites quelques sauts conceptuels.

Allons à la nitty gritty.

Tout d'abord, Angular ne remplace pas jQuery

Angulaire et jQuery font des choses différentes. AngularJS vous donne 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 parfaitement utilisable de jQuery.

Misko aime jQuery et ne s'oppose pas à ce que vous l'utilisiez. Cependant, au fur et à mesure que vous avancerez, vous pourrez réaliser à peu près tout votre travail en utilisant une combinaison d'étendues, de modèles et de directives, et préférerez ce flux de travail parce que votre code sera plus discret, plus configurable et plus Angulaire.

Si vous utilisez jQuery, vous ne devriez pas l'arroser partout. L'emplacement correct pour la manipulation DOM dans AngularJS est dans une directive. Plus sur ces derniers plus tard.

JavaScript discret avec sélecteurs et 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 très mauvais.

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.

Quand vous voyez cela pour la première fois, vous pourriez être tenté d'écrire AngularJS comme JavaScript intrusif old school (comme je l'ai fait au début). En fait, AngularJS ne joue pas avec 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 le 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 devrait être déclaratif. sa signification devrait être claire simplement en la lisant. Nous utilisons des attributs personnalisés avec des noms significatifs. Nous composons de nouveaux éléments HTML, toujours avec des noms significatifs. Un concepteur ayant une connaissance HTML minimale et aucune compétence de codage peut lire votre modèle AngularJS et comprendre ce qu'il fait. Il ou elle peut faire des modifications. C'est la manière angulaire.

Le modèle est dans le siège du conducteur.

Une des premières questions que je me suis posé au début de AngularJS et à travers les tutoriels est "Où est mon code?". Je n'ai pas écrit de JavaScript, et pourtant j'ai tout ce comportement. La réponse est évidente. Parce que AngularJS compile le DOM, AngularJS traite votre code 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. C'est traité comme un DSL. Vous écrivez des composants AngularJS, et AngularJS prendra soin de les insérer et de les rendre disponibles au bon moment en fonction de la structure de votre template. Ceci est très différent d'une norme MVC modèle, où le modèle est juste pour la sortie.

C'est plus similaire à XSLT que Ruby sur Rails par exemple.

C'est une inversion radicale du contrôle qui prend un peu de temps pour s'y habituer.

Arrêtez d'essayer de conduire votre application à partir de votre JavaScript. Laissez le template piloter l'application, et laissez AngularJS prendre soin de câbler les composants ensemble. C'est aussi la manière angulaire.

HTML sémantique vs modèles sémantiques

Avec jQuery, votre page HTML doit contenir du contenu significatif et 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 en fin de compte 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, mais votre API et votre DOM compilé sont sémantiques.

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

À ce stade, vous avez probablement toutes sortes de questions concernant SEO et l'accessibilité, et à juste titre. Il y a des problèmes ouverts ici. La plupart des lecteurs d'écran vont maintenant analyser JavaScript. Les moteurs de recherche peuvent également indexer AJAXed contenu. Néanmoins, vous voudrez vous assurer que vous utilisez des URL pushstate et que vous avez un sitemap décent. Voir ici pour une discussion de la question: https://stackoverflow.com/a/23245379/687677

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

Séparation des préoccupations (SOC) est un modèle qui a grandi au cours de nombreuses années de développement Web pour une variété de raisons, y compris le référencement, l'accessibilité et l'incompatibilité de navigateur. Cela ressemble à ceci:

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

Encore une fois, AngularJS ne joue pas selon leurs 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, pas même un peu.

Cela ressemble à ceci:

  1. Modèle - vos modèles contiennent vos données sémantiques. Les modèles sont généralement JSON objets. 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. Voir - Vos opinions 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 relie 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 de navigateur, vous pourriez trouver cette idée assez choquante. Dépasse-le, ça vaudra le coup, je te le promets.

Plugins ou 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 attachons ensuite dans le 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 de figures non ordonnée, peut-être enveloppée dans un élément nav. Vous pouvez alors écrire un peu de jQuery pour sélectionner la liste sur la page et la remodeler comme une galerie avec des délais pour faire l'animation glissante.

En AngularJS, nous définissons des directives. Une directive est une fonction qui retourne un objet JSON. Cet objet indique à AngularJS quels éléments DOM rechercher, et quels changements y apporter. Les directives sont lié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.

Le moyen AngularJS est d'étendre les capacités du HTML natif. Vous devriez écrire du HTML qui ressemble au 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 insérer un modèle et faire fonctionner ce meunier.

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

La tendance avec jQuery est d'écrire de grands plugins comme lightbox que nous configurons ensuite en passant dans 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 dropdown vous pourriez être tenté de coder dans les gestionnaires de clic, peut-être une fonction à ajouter dans un chevron qui est soit haut ou bas, peut-être changer la classe de l'élément déplié, montrer cacher le menu,

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 été câblé dans notre gestionnaire de clic pour nous, nous allons devoir ajouter une option de configuration pour le faire se comporter différemment dans ce cas précis.

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

À présent dans notre template on peut câbler ça:

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

Besoin de mettre à jour sur mouseover?

<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 la granularité au niveau HTML. Si nous voulons faire des exceptions au cas par cas, le modèle rend cela facile.

Fermeture contre $ scope

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 noeuds DOM passés au plugin par jQuery, plus toutes les variables locales définies dans la fermeture et toutes les globales que vous avez définies. Cela signifie que les plugins sont assez autonomes. C'est une bonne chose, mais peut devenir restrictive lors de la création d'une application entière. Essayer de transmettre des données entre des sections d'une page dynamique devient une corvée.

AngularJS a des objets $ scope. Ce sont des objets spéciaux créés et gérés par AngularJS dans lesquels vous stockez votre modèle. Certaines directives génèrent une nouvelle $ $, qui hérite par défaut de son enveloppe $ scope en utilisant l'héritage prototypique JavaScript. L'objet $ scope est accessible dans le contrôleur et dans la vue.

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

Cela facilite le transfert des données et le stockage des données à un niveau approprié. Si une liste déroulante est déroulée, seule la liste déroulante $ scope doit en être informée. Si l'utilisateur met à jour ses préférences, vous pouvez mettre à jour l'étendue globale $ et toutes les étendues imbriquées écoutant les préférences utilisateur seront automatiquement alertées.

Cela peut sembler compliqué, en fait, une fois que vous vous y relaxez, 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 la hiérarchie de votre modèle. AngularJS le met ensuite à la disposition de votre composant en utilisant la magie de l'injection de dépendance (plus de détails plus loin).

Modifications manuelles de DOM par rapport à la liaison de données

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

Dans AngularJS, vous pouvez le faire aussi, mais vous êtes encouragé à utiliser la liaison de données. Changez votre modèle, et parce que le DOM est lié à celui-ci via un template, votre DOM sera automatiquement mis à jour, aucune intervention requise.

Étant donné que la liaison de données est effectuée à partir du modèle, en utilisant un attribut ou la syntaxe d'accolade, il est très facile à faire. Il y a peu de frais généraux cognitifs associés, donc vous vous retrouverez à 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 met à jour la valeur dans votre portée actuelle, et vice-versa.

Également:

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

affichera le nom d'utilisateur dans un paragraphe. C'est une liaison en direct, donc si le $scope.user.name La valeur est mise à jour, le modèle sera également mis à jour.

Ajax tout le temps

En jQuery faire un appel Ajax est assez simple, mais c'est encore quelque chose que vous pourriez penser à deux fois. Il y a la complexité supplémentaire à laquelle il faut réfléchir, et une bonne partie du script à maintenir.

Dans AngularJS, Ajax est votre solution par défaut et cela arrive tout le temps, presque sans que vous 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 envelopper un appel Ajax dans un service et créer vous-même un GitHub service, ou un Flickr service, auquel vous pouvez accéder avec une facilité étonnante.

Objets de service et fonctions d'assistance

Dans jQuery, si nous voulons accomplir une petite tâche non liée au dom, comme tirer un flux d'une API, nous pourrions é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 à ce flux souvent? 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. Ils sont toujours singletons, ce qui signifie qu'il ne peut jamais y en avoir plus d'un. Disons que nous voulons accéder à l'API Stack Overflow, nous pourrions écrire un StackOverflowService qui définit les méthodes pour le faire.

Disons que nous avons un panier. Nous pourrions définir un ShoppingCartService qui gère notre panier et contient des méthodes pour ajouter et supprimer des éléments. Comme le service est un singleton et qu'il est partagé par tous les autres composants, tout objet qui en a besoin peut écrire dans le panier et en extraire des données. C'est toujours le même panier.

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 à un endroit, vous pouvez obtenir ces données ailleurs simplement en demandant le même service.

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

AngularJS gère vos dépendances pour vous. Si vous voulez un objet, il vous suffit de vous y référer et AngularJS l'obtiendra pour vous.

Jusqu'à ce que vous commenciez à l'utiliser, il est difficile d'expliquer à quel point cela est énorme. Rien de tel que AngularJS DI n'existe à l'intérieur de 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.

Dites que j'ai un composant appelé 'FlickrService' qui définit les méthodes pour extraire les flux JSON à partir de Flickr. Maintenant, si je veux écrire un contrôleur qui peut accéder à Flickr, j'ai juste besoin de me référer au 'FlickrService' par son nom quand je déclare le contrôleur. AngularJS prendra soin d'instancier le composant et de le rendre disponible à 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 facilite le câblage et élimine pratiquement toute tendance à la spagetification. Nous avons une liste de composants, et AngularJS nous les donne un par un quand nous en avons besoin.

Architecture de service modulaire

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

AngularJS vous donne 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 envelopper 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 dépendra votre application.

Vous obtenez une réutilisation de code simple, si vous voulez écrire une autre application basée sur Flickr, vous pouvez simplement inclure le module Flickr et voila, 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 en tant que 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 de 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 (templates, data-binding, $ scope, directives, etc.), vous trouverez un lot moins de jQuery que ce que vous pourriez demander.

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. Écrivez plutôt des petites directives qui font une chose, puis écrivez un simple modèle pour les relier.

Pensez moins à JavaScript discret, et pensez plutôt en termes d'extensions HTML.

Mon petit livre

AngularJS m'a tellement enthousiasmé que j'ai écrit un petit livre que vous pouvez lire en ligne http://nicholasjohnson.com/angular-book/. J'espère que c'est utile.


184
2018-05-12 10:22



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

Impératif vs déclaratif

Avec jQuery vous dites au DOM ce qui doit arriver, étape par étape. Avec AngularJS vous décrivez les résultats que vous voulez mais pas comment le faire. Plus à ce sujet ici. Aussi, consultez la réponse de Mark Rajcok.

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

AngularJS est un cadre client complet qui utilise le MVC motif (consultez leur représentation graphique). Il se concentre beaucoup sur la séparation des préoccupations.

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

jQueryest une bibliothèque

AngularJS est un beau cadre côté client, hautement testable, qui combine des tonnes de trucs sympas comme MVC, injection de dépendance, liaison de données et bien plus encore.

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

La meilleure façon de commencer est de passer par leur didacticiel génial. Vous pouvez passer par les étapes dans quelques heures; cependant, au cas où vous voudriez maîtriser les concepts derrière les scènes, ils incluent une myriade de référence pour davantage de lecture.

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

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

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


152
2018-02-21 04:29



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

AngularJS change la façon dont vous trouver éléments

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

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

AngularJS n'a pas besoin (ou ne veut pas) de vous pour trouver des éléments en utilisant des sélecteurs - la principale différence entre AngularJS jqLite contre à part entière jQuery est-ce jqLite ne supporte pas les sélecteurs.

Donc quand les gens disent "n'incluent pas jQuery du tout", 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, ne sélectionnez pas!


84
2018-02-21 07:57



jQuery

jQuery fait des commandes JavaScript ridiculement longues comme getElementByHerpDerp plus court et cross-browser.

AngularJS

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

Modifier:

Dire "J'ai un fond de jQuery comment je pense dans AngularJS?" est comme dire "J'ai un arrière-plan HTML, comment je pense 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 qu'en parcourant la liste en disant "AngularJS utilise des directives alors que jQuery utilise des sélecteurs CSS pour faire un objet jQuery qui fait ceci et cela etc ...." . Cette question ne nécessite pas une réponse longue.

jQuery est un moyen de faciliter la programmation de JavaScript dans le navigateur. Des raccourcis, des commandes inter-navigateurs, etc.

AngularJS étend HTML, de sorte que vous n'avez pas à mettre <div> partout juste pour faire une demande. Il fait en sorte que le HTML fonctionne pour les applications plutôt que pour ce à quoi il a été conçu, c'est-à-dire des pages web éducatives statiques. Il accomplit ceci d'une manière détournée en utilisant JavaScript, mais fondamentalement c'est une extension de HTML, pas de JavaScript.


69
2018-02-04 05:07



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 à partir de cet angle.

Par exemple, lorsque vous obtenez des données du serveur que vous avez l'intention d'afficher dans un format quelconque dans le DOM, dans jQuery, vous devez '1. TROUVEZ 'où dans le DOM vous voulez placer ces données, le' 2. UPDATE / APPEND 'il là en créant un nouveau noeud ou juste en définissant son innerHTML. Ensuite, quand vous voulez mettre à jour cette vue, vous avez alors '3. TROUVER 'l'emplacement et' 4. METTRE À JOUR'. Ce cycle de recherche et de mise à jour, effectué dans le même contexte d'obtention et de formatage des données à partir du serveur, est terminé dans AngularJS.

Avec AngularJS vous avez votre modèle (objets JavaScript 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 devez pas Je dois y penser. Vous vous retrouverez dans AngularJS ne trouvant plus rien dans le DOM.

En d'autres termes, dans jQuery, vous devez penser aux sélecteurs CSS, c'est-à-dire, où est le div ou td qui a une classe ou un attribut, etc., pour que je puisse obtenir leur HTML ou couleur ou valeur, mais dans AngularJS, vous vous surprendrez à penser comme ceci: de quel modèle ai-je affaire, je vais définir la valeur du modèle à true. 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 (détails que vous auriez souvent besoin de prendre en compte dans jQuery).

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

Encore une chose que vous expérimenterez 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 Habituellement, cela signifie apprendre ce que AngularJS veut 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 font d'AngularJS un framework plutôt qu'une bibliothèque.


61
2017-11-02 16:53



Ce sont des réponses très belles, mais longues.

Pour résumer mes expériences:

  1. Les contrôleurs et les fournisseurs (services, usines, etc.) sont pour modifier le modèle de données, PAS HTML.
  2. HTML et les directives définissent la mise en page et la liaison au modèle.
  3. Si vous avez besoin de partager des données entre contrôleurs, créez un service ou une fabrique: ce sont des singletons partagés dans 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 de mettre à jour HTML ... STOP! mettez à jour le modèle et assurez-vous que votre code HTML est lié au modèle.

46
2018-05-16 21:50