Mostrar ventanas emergentes de la manera más elegante

178

Tengo esta aplicación AngularJS. Todo funciona bien.

Ahora necesito mostrar diferentes ventanas emergentes cuando las condiciones específicas se vuelven realidad, y me preguntaba cuál sería la mejor manera de proceder.

Actualmente estoy evaluando dos opciones, pero estoy absolutamente abierto a otras opciones.


Opción 1

Podría crear el nuevo elemento HTML para la ventana emergente y agregarlo al DOM directamente desde el controlador.

Esto romperá el patrón de diseño MVC. No estoy contento con esta solución.


opcion 2

Siempre podría insertar el código para todas las ventanas emergentes en el archivo HTML estático. Luego, usando ngShow, puedo ocultar / mostrar solo la ventana emergente correcta.

Esta opción no es realmente escalable.


Así que estoy bastante seguro de que tiene que haber una mejor manera de lograr lo que quiero.

Bruno
fuente
numerosas maneras, controlador de html definitivamente es no buena manera, vistazo a la interfaz de usuario modal Bootstrap angular-ui.github.com/bootstrap/#/modal
charlietfl
1
Los documentos de AngularJS explican un poco cómo administrar ventanas emergentes, en la sección ' Comprensión de la transclusión y los ámbitos '. Espero que esto ayude.
Ivan Ferrer Villa
Si realmente desea escalar con ventanas emergentes, consulte popscript .
Raj Nathani

Respuestas:

88

Según mi experiencia con los modales de AngularJS hasta el momento, creo que el enfoque más elegante es un servicio dedicado al que podemos proporcionar una plantilla parcial (HTML) para que se muestre en modo modal.

Cuando pensamos en ello, los modales son una especie de rutas AngularJS pero solo se muestran en una ventana emergente modal.

El proyecto de arranque de AngularUI ( http://angular-ui.github.com/bootstrap/ ) tiene un excelente $modalservicio (solía llamarse $ dialog antes de la versión 0.6.0) que es una implementación de un servicio para mostrar el contenido parcial como una ventana emergente modal.

pkozlowski.opensource
fuente
10
$ dialog ahora es $ modal
Sangram Singh
1
@ pkozlowski.opensource Me gusta el enfoque de ui-bootstrap, sin embargo, parece que no puedo traducir el contenido con el modal. Lo he investigado un poco y veo que otras personas también tienen este problema.
jusopi
2
weblogs.asp.net/dwahlin/building-an-angularjs-modal-service Encontré este artículo muy útil.
JenonD
Solo por mencionar que un servicio no debe acceder al DOM. Una directiva es el lugar para esto.
superluminary
1
@superluminary esta es una buena regla general a seguir, pero también es bueno saber por qué cierta regla está en ritmo y entender cuándo dicha regla puede (o incluso debería) romperse. Creo que modals / tooltips y similares son una excepción a la regla. En resumen: uno necesita conocer las reglas pero también entender el contexto en el que se aplican / no se aplican.
pkozlowski.opensource
29

Es divertido porque estoy aprendiendo Angular y estaba viendo algunos videos de su canal en Youtube. El orador menciona su problema exacto en este video https://www.youtube.com/watch?v=ZhfUv0spHCY#t=1681 alrededor de las 28:30 minutos.

Todo se reduce a colocar ese fragmento de código en particular en un servicio en lugar de un controlador.

Mi suposición sería inyectar nuevos elementos emergentes en el DOM y manejarlos por separado en lugar de mostrar y ocultar el mismo elemento. De esta manera puede tener múltiples ventanas emergentes.

Todo el video también es muy interesante de ver :-)

Bart
fuente
2
¡Misko es la semilla de angular! (bwa jaja). En serio, aunque. Considere sus palabras como la fuente definitiva de angular.
Mazo del
14
  • Cree una directiva 'emergente' y aplíquela al contenedor del contenido emergente
  • En la directiva, envuelva el contenido en una posición absoluta div junto con la máscara div debajo de ella.
  • Está bien mover los 2 divs en el árbol DOM según sea necesario dentro de la directiva. Cualquier código de IU está bien en las directivas, incluido el código para colocar la ventana emergente en el centro de la pantalla.
  • Cree y enlace una bandera booleana al controlador. Esta bandera controlará la visibilidad.
  • Cree variables de alcance que se unan a las funciones OK / Cancelar, etc.

Edición para agregar un ejemplo de alto nivel (no funcional)

<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
fuente
$ watch en lugar de 'watch'. ¿No debería ser 'popup' en lugar de 'showPopup' scope.watch(showPopup, function(newVal, oldVal){?
Sangram Singh
14

Ver http://adamalbrecht.com/2013/12/12/creating-a-simple-modal-dialog-directive-in-angular-js/ para una forma simple de hacer un diálogo modal con Angular y sin necesidad de bootstrap

Editar: desde entonces he estado usando ng-dialog de http://likeastore.github.io/ngDialog, que es flexible y no tiene dependencias.

Nik Dow
fuente
1
Solo hice un sprint rápido con este enfoque solo para darme cuenta de que esto es genial para un solo enfoque emergente / modal, sin embargo, piense en esta experiencia de usuario particular: digamos que un cliente está ordenando un artículo, y la interfaz de usuario presenta una ventana emergente de confirmación de pedido (así que 'he' ocupado 'la ventana emergente de Adam con contenido). Ahora hacemos clic en enviar o comprar o lo que sea de esa ventana emergente, y hay un error por el cual el usuario necesita modificar ese orden en la pantalla anterior. Quiero mostrar ese error en otra ventana emergente en el nivel superior. Este enfoque no facilita esto, no lo creo.
jusopi
3
Es cierto, pero creo que más de una ventana emergente podría ser una interfaz de usuario pobre.
Nik Dow
bueno, el complemento es la respuesta que estaba buscando!
Andrés Felipe
7

Angular-ui viene con una directiva de diálogo. Úselo y configure templateurl en la página que desee incluir. Esa es la forma más elegante y también la he usado en mi proyecto. Puede pasar varios otros parámetros para el diálogo según las necesidades.

user2203937
fuente
55
angular-bootstrap 0.6 en adelante ha reemplazado $ dialog con $ modal. Eso significa que debe cambiar todo el código que usa $ dialog ya que está en desuso y escribirlo en $ modal
Mohammad Umair Khan