Lequel est considéré comme meilleur:
- avoir une directive qui interagit directement avec les services
ou
- avoir une directive exposant certains points d'ancrage à quel contrôleur peut lier un comportement (impliquant des services)?
Lequel est considéré comme meilleur:
ou
Réponses:
En règle générale, une directive est préférable lorsqu'elle est courte (en termes de code), (potentiellement) réutilisable et qu'elle a une portée limitée en termes de fonctionnalités. Faire une directive qui inclut l'interface utilisateur et dépend d'un service (qui, je suppose, gère la connexion au backend), ne lui donne pas seulement 2 rôles fonctionnels, à savoir:
mais aussi en le rendant moins réutilisable, car vous ne pourrez plus l'utiliser avec un autre service, ou avec une interface utilisateur différente (du moins, pas facilement).
Lorsque je prends ces décisions, je compare souvent les éléments HTML intégrés: par exemple <input>
, <textarea>
ou <form>
: ils sont complètement indépendants d’un backend spécifique. HTML5 a donné à l' <input>
élément quelques types supplémentaires, par exemple date
, qui sont toujours indépendants du backend et où se trouvent exactement les données ou comment elles sont utilisées. Ils sont purement des éléments d'interface. Je pense que vos widgets personnalisés, construits en utilisant des directives, devraient suivre le même schéma, si possible.
Cependant, ce n'est pas la fin de l'histoire. Au-delà de l'analogie avec les éléments HTML intégrés, vous pouvez créer des directives réutilisables appelant des services et utiliser une directive purement interface utilisateur, comme si elle utilisait a <textarea>
. Supposons que vous souhaitiez utiliser du code HTML comme suit:
<document document-url="'documents/3345.html'">
<document-data></document-data>
<comments></comments>
<comment-entry></comment-entry>
</document>
Pour coder la commentEntry
directive, vous pouvez créer une très petite directive qui ne contient que le contrôleur qui relie un service à un widget UI. Quelque chose comme:
app.directive('commentEntry', function (myService) {
return {
restrict: 'E',
template: '<comment-widget on-save="save(data)" on-cancel="cancel()"></comment-widget>',
require: '^document',
link: function (scope, iElement, iAttrs, documentController) {
// Allow the controller here to access the document controller
scope.documentController = documentController;
},
controller: function ($scope) {
$scope.save = function (data) {
// Assuming the document controller exposes a function "getUrl"
var url = $scope.documentController.getUrl();
myService.saveComments(url, data).then(function (result) {
// Do something
});
};
}
};
});
À la limite, vous n'aurez peut-être jamais besoin d'un ng-controller
attribut manuel dans le code HTML: vous pouvez tout faire à l'aide de directives, à condition que chacun ait directement un rôle "d'interface utilisateur" ou un rôle "de données" clair.
Il y a un inconvénient que je devrais mentionner: cela donne plus de "pièces mobiles" à l'application, ce qui ajoute un peu de complexité. Cependant, si chaque partie a un rôle clair et est bien (unité + E2E testée), je dirais que cela en vaut la peine et représente un avantage global à long terme.
Permettez-moi d'être en désaccord avec la réponse de Michal Charemza.
Bien que sa réponse soit théoriquement correcte, elle n’est pas très pratique dans le monde réel.
Je dis cela parce que j’avais l'habitude de penser comme ça et d'essayer de l'appliquer à une grande application du monde réel que moi-même et mon équipe développons et que cela est devenu trop gênant.
L'analogie avec le langage HTML n'est pas bonne, car vous ne devriez pas vous efforcer de créer des directives d'usage général extrêmement réutilisables, car vous ne construisez pas une application générique comme un navigateur Web.
Vous devez plutôt utiliser les directives pour créer un langage DSL (Domain Specific Language) pour votre application, qui réside sur son propre domaine.
Cela ne signifie pas que toutes les directives ne doivent pas être génériques. Certains pourraient être, si c'est dans leur nature. Si vous construisez un sélecteur de date personnalisé, rendez-le générique et réutilisable dans toutes les applications.
Mais si vous construisez quelque chose comme une boîte de connexion qui se lie à votre back-end, faites-le.
La seule règle empirique devrait être la suivante: ne dupliquez jamais le code (fragments abstraits à des usines et des services) et faites-le tester via l'injection de dépendance. Heureusement, avec Angular, ce sont des gâteaux.
Rester simple. :)
Je pense que la question "une directive doit-elle interagir avec un service" dépend de ce que fait votre service.
J'ai vu des directives interagir avec des services qui ne font rien avec les requêtes HTTP et je pense que c'est un bon modèle. Les services / usines sont parfaits pour encapsuler plus de logique orientée données, et les directives sont parfaits pour encapsuler une logique orientée présentation. L'objectif déclaré des services dans la documentation angulaire est le suivant: "Vous pouvez utiliser des services pour organiser et partager du code dans votre application.". C'est assez large, mais les services peuvent être utilisés pour atteindre cet objectif dans les directives.
Cela étant dit, je comprends dans certains cas le désir de faire en sorte que les directives ne fassent pas directement de requêtes HTTP. Encore une fois, cela dépend du service et de la façon dont vous organisez vos services.
Selon le framework AngularJS, nous devrions singleton des usines / services pour obtenir toutes les données du serveur. Pour que ces usines puissent être réutilisées d'une application à l'autre sans avoir à réécrire la même. Bien à l'intérieur de la directive, nous pouvons appeler ces usines pour récupérer les données depuis Api / server.