Afficher les pop-ups de la manière la plus élégante

178

J'ai cette application AngularJS. Tout fonctionne très bien.

Maintenant, je dois afficher différentes fenêtres contextuelles lorsque des conditions spécifiques deviennent vraies, et je me demandais quelle serait la meilleure façon de procéder.

Actuellement, j'évalue deux options, mais je suis absolument ouvert à d'autres options.


Option 1

Je pourrais créer le nouvel élément HTML pour le pop-up et l'ajouter au DOM directement à partir du contrôleur.

Cela cassera le modèle de conception MVC. Je ne suis pas satisfait de cette solution.


Option 2

Je pourrais toujours insérer le code de toutes les fenêtres contextuelles dans le fichier HTML statique. Ensuite, en utilisant ngShow, je peux masquer / afficher uniquement la fenêtre contextuelle correcte.

Cette option n'est pas vraiment évolutive.


Je suis donc presque sûr qu'il doit y avoir une meilleure façon de réaliser ce que je veux.

Bruno
la source
de nombreuses façons, le contrôleur pour html n'est certainement pas bon, regardez UI Bootstrap Modal angular-ui.github.com/bootstrap/#/modal
charlietfl
1
Les documents d'AngularJS expliquent un peu comment gérer les popups, dans la section `` Comprendre la transclusion et les portées ''. J'espère que cela t'aides.
Ivan Ferrer Villa
Si vous voulez vraiment mettre à l'échelle avec des popups, consultez popscript .
Raj Nathani

Réponses:

88

Sur la base de mon expérience avec les modaux AngularJS jusqu'à présent, je pense que l'approche la plus élégante est un service dédié auquel nous pouvons fournir un modèle partiel (HTML) à afficher dans un modal.

Quand on y pense, les modaux sont des sortes de routes AngularJS mais juste affichés dans un popup modal.

Le projet d'amorçage AngularUI ( http://angular-ui.github.com/bootstrap/ ) a un excellent $modalservice (anciennement appelé $ dialog avant la version 0.6.0) qui est une implémentation d'un service pour afficher le contenu partiel comme un popup modal.

pkozlowski.opensource
la source
10
$ dialog est maintenant $ modal
Sangram Singh
1
@ pkozlowski.opensource J'aime l'approche de ui-bootstrap, mais je n'arrive pas à transclure le contenu avec le modal. J'en ai fait des recherches et j'ai vu que d'autres personnes avaient également ce problème.
jusopi du
2
weblogs.asp.net/dwahlin/building-an-angularjs-modal-service J'ai trouvé cet article très utile.
JenonD
Juste pour mentionner, un service ne doit pas accéder au DOM. Une directive est le lieu pour cela.
Superluminary
1
@superluminary c'est en effet une bonne règle générale à suivre, mais c'est aussi dieu de savoir pourquoi une certaine règle est en rythme et de comprendre quand une telle règle peut (ou même devrait!) être enfreinte. Je crois que les modaux / info-bulles et autres font exception à la règle. En bref: il faut connaître les règles mais aussi comprendre le contexte dans lequel celles-ci s'appliquent / ne s'appliquent pas.
pkozlowski.opensource
29

C'est drôle parce que j'apprends moi-même Angular et que je regardais des vidéos de leur chaîne sur Youtube. L'orateur mentionne votre problème exact dans cette vidéo https://www.youtube.com/watch?v=ZhfUv0spHCY#t=1681 autour de 28h30.

Cela revient à placer ce morceau de code particulier dans un service plutôt que dans un contrôleur.

Ma conjecture serait d'injecter de nouveaux éléments popup dans le DOM et de les gérer séparément au lieu d'afficher et de cacher le même élément. De cette façon, vous pouvez avoir plusieurs fenêtres contextuelles.

La vidéo entière est également très intéressante à regarder :-)

Bart
la source
2
Misko est la graine d'angular! (bwa haha). Sérieusement tho. Considérez ses paroles comme la source définitive de angular.
pont du
14
  • Créez une directive 'popup' et appliquez-la au conteneur du contenu popup
  • Dans la directive, enveloppez le contenu dans une position absolue div avec le masque div en dessous.
  • Il est possible de déplacer les 2 div dans l'arborescence DOM selon les besoins à partir de la directive. Tout code d'interface utilisateur est OK dans les directives, y compris le code pour positionner la popup au centre de l'écran.
  • Créez et liez un indicateur booléen au contrôleur. Cet indicateur contrôlera la visibilité.
  • Créez des variables de portée qui se lient aux fonctions OK / Annuler, etc.

Modification pour ajouter un exemple de haut niveau (non fonctionnel)

<div id='popup1-content' popup='showPopup1'>
  ....
  ....
</div>


<div id='popup2-content' popup='showPopup2'>
  ....
  ....
</div>



.directive('popup', function() {
  var p = {
      link : function(scope, iElement, iAttrs){
           //code to wrap the div (iElement) with a abs pos div (parentDiv)
          // code to add a mask layer div behind 
          // if the parent is already there, then skip adding it again.
         //use jquery ui to make it dragable etc.
          scope.watch(showPopup, function(newVal, oldVal){
               if(newVal === true){
                   $(parentDiv).show();
                 } 
              else{
                 $(parentDiv).hide();
                }
          });
      }


   }
  return p;
});
Ketan
la source
$ watch au lieu de «watch». aussi shd n'est-ce pas «popup» au lieu de «showPopup» dans scope.watch(showPopup, function(newVal, oldVal){?
Sangram Singh
14

Voir http://adamalbrecht.com/2013/12/12/creating-a-simple-modal-dialog-directive-in-angular-js/ pour un moyen simple de faire un dialogue modal avec Angular et sans avoir besoin de bootstrap

Edit: depuis, j'utilise ng-dialog de http://likeastore.github.io/ngDialog qui est flexible et n'a aucune dépendance.

Nik Dow
la source
1
Je viens de faire un sprint rapide avec cette approche pour me rendre compte que c'est génial pour une approche contextuelle / modale unique, mais pensez à cette UX particulière: disons qu'un client commande un article et que l'interface utilisateur présente une fenêtre contextuelle de confirmation de commande (donc nous 'ai' occupé 'le popup d'Adam avec du contenu) Maintenant, nous cliquons sur envoyer ou acheter ou quoi que ce soit dans cette fenêtre contextuelle, et il y a une erreur dans laquelle l'utilisateur doit modifier cette commande dans l'écran précédent. Je veux afficher cette erreur dans une autre fenêtre contextuelle au niveau supérieur. Cette approche ne facilite pas cela, je ne crois pas.
jusopi
3
C'est vrai, mais je pense que plus d'une fenêtre contextuelle pourrait être une mauvaise interface utilisateur.
Nik Dow
et bien le plugin est la réponse que je cherchais!
Andres Felipe
7

Angular-ui est livré avec une directive dialog. Utilisez-la et définissez templateurl sur la page que vous souhaitez inclure. C'est la manière la plus élégante et je l'ai également utilisée dans mon projet. Vous pouvez passer plusieurs autres paramètres pour le dialogue selon les besoins.

user2203937
la source
5
angular-bootstrap 0.6 et les versions ultérieures ont remplacé $ dialog par $ modal. Cela signifie que vous devez changer tout le code qui utilise $ dialog car il est obsolète et l'écrire dans $ modal
Mohammad Umair Khan