Séparation de la manipulation DOM des contrôleurs angulaires – Meilleure pratique recherchée

En essayant de trouver la meilleure façon de construire une application angulaire, j'ai trouvé plusieurs articles sur les meilleures pratiques. Avec cette contribution, j'ai fait ceci:

angular.module('xApp', []) //..... some services, factories, controllers, .... .directive('dirNotification',[ function dirNotification() { return { scope: {}, templateUrl: 'xNotification.html', replace: true, controller: 'CtrlNotification', link: function($scope){ // if this is 'DOM manipulation, should be done here ... ? /* $scope.$on('session.update',function(event, args) { if (args == null) { $scope.notificationdata.username = ""; $scope.notificationdata.sid = ""; } else { $scope.notificationdata.username = args.username; $scope.notificationdata.sid = args.accessToken; } }); */ } }; }]) .controller('CtrlNotification',['$scope' ,function CtrlNotification($scope) { $scope.notificationdata = { username: "", sid: "" }; // this is not real DOM manipulation, but only view data manipulation? $scope.$on('session.update',function(event, args) { if (args == null) { $scope.notificationdata.username = ""; $scope.notificationdata.sid = ""; } else { $scope.notificationdata.username = args.username; $scope.notificationdata.sid = args.accessToken; } }); }]) 

Le modèle HTML est tout simplement ceci:

 <div> <p>{{notificationdata.username}}</p> <p>{{notificationdata.sid}}</p> </div> 

Donc, ma question est, les changements de données devraient-ils être considérés comme une manipulation DOM? La version actuelle qui fait cela dans le contrôleur me semble plus pratique (par exemple, définir des valeurs par défaut). De plus, si j'ajoute plus de fonctionnalités à cela, le bloc de "lien de directive" augmentera et contiendra plus de fonctions que les définitions. Je suppose que dans la directive, des choses comme changer des couleurs ou des éléments cachés selon les données de portée devraient être faites là.

Que signifie la communauté? Êtes-vous d'accord avec mes hypothèses?

Merci Rainer

Comme un bon début, lisez cette question / réponse .

Contrôleurs:

La raison pour laquelle vous ne devez pas faire de manipulation de DOM (ou la recherche d'éléments de DOM, ou de faire des hypothèses sur la vue, en fait) dans le contrôleur est parce que l'intention du contrôleur est de traiter uniquement l'état de l'application – par En changeant le ViewModel – indépendamment de la façon dont l'état est reflété dans la vue. Ce contrôleur le fait en réagissant aux événements du modèle et des propriétés View et setting du ViewModel. Angular traitera le fait de refléter l'état de l'application dans la vue avec les liaisons.

Donc oui, évidemment, changer le ViewModel fait réagir l'affichage et le DOM à manipuler, mais l'idée est que le contrôleur ne doit pas savoir ou se soucier de la façon dont la vue réagit. Cela empêche la séparation des préoccupations intactes.

Directives:

Lorsque les directives intégrées ne sont pas suffisantes et que vous avez besoin d'un contrôle plus strict sur la façon dont la View réagit, c'est une bonne raison de créer une directive personnalisée.

Deux choses à rappeler sur les directives.

1) Il est utile de penser aux directives en tant que composants réutilisables, de sorte qu'il y a moins de logique spécifique à l'application, mieux c'est. Et certainement, évitez toute logique commerciale là-bas. Définissez les entrées et les sorties (généralement via les attributs) et réagissez uniquement à ceux-ci. Les auditeurs d'événements (comme vous l'avez fait) sont très spécifiques à l'application (à moins que cette directive ne soit utilisée avec une autre directive qui publie un événement), il est donc préférable d'éviter, si possible.

 .directive("notification", function(){ return { restrict: "A", scope: { notification: "=" // let the attribute get the data for notification, rather than // use scope.$on listener }, // ... } }) 

2) Juste parce que les directives sont "autorisées à faire des manipulations DOM" ne signifie pas que vous devriez oublier la séparation ViewModel-View. Angulaire vous permet de définir la portée dans un lien ou une fonction de contrôleur, et fournir un modèle avec toutes les expressions et liaisons angulaires typiques.

 template: '<div ng-show="showNotification">username:{{notification.username}}</div>', // controller could also have been used here link: function(scope, element, attrs){ scope.showNotification = Math.floor(Math.random()* 2); }