Mostre pop-ups da maneira mais elegante

178

Eu tenho esse aplicativo AngularJS. Tudo funciona muito bem.

Agora, preciso mostrar pop-ups diferentes quando condições específicas se tornarem verdadeiras, e fiquei imaginando qual seria a melhor maneira de proceder.

Atualmente, estou avaliando duas opções, mas estou absolutamente aberto a outras opções.


Opção 1

Eu poderia criar o novo elemento HTML para o pop-up e anexar ao DOM diretamente do controlador.

Isso quebrará o padrão de design do MVC. Não estou feliz com esta solução.


opção 2

Eu sempre poderia inserir o código para todos os pop-ups no arquivo HTML estático. Em seguida, usando ngShow, eu posso ocultar / mostrar apenas o pop-up correto.

Esta opção não é realmente escalável.


Portanto, tenho certeza de que deve haver uma maneira melhor de conseguir o que quero.

Bruno
fonte
inúmeras maneiras, controlador para html defintiely não boa forma, olhada UI Bootstrap Modal angular-ui.github.com/bootstrap/#/modal
charlietfl
1
Os documentos do AngularJS explicam um pouco como gerenciar pop-ups, na seção ' Noções básicas sobre transclusão e escopos '. Espero que isto ajude.
7267 Ivan Ferrer Villa
Se você realmente deseja escalar com pop-ups, confira popscript .
Raj Nathani

Respostas:

88

Com base na minha experiência com os modais AngularJS até agora, acredito que a abordagem mais elegante seja um serviço dedicado ao qual possamos fornecer um modelo parcial (HTML) a ser exibido em um modal.

Quando pensamos nisso, os modais são uma espécie de rotas AngularJS, mas apenas exibidas no pop-up modal.

O projeto de inicialização do AngularUI ( http://angular-ui.github.com/bootstrap/ ) possui um excelente $modalserviço (costumava ser chamado de $ dialog antes da versão 0.6.0) que é uma implementação de um serviço para exibir o conteúdo de parcial como um pop-up modal.

pkozlowski.opensource
fonte
10
$ dialog agora é $ modal #
Sangram Singh 10/10
1
@ pkozlowski.opensource Gosto da abordagem do ui-bootstrap, mas não consigo transcluir o conteúdo com o modal. Eu pesquisei um pouco e vi outras pessoas com esse problema também.
11134 jusopi
2
weblogs.asp.net/dwahlin/building-an-angularjs-modal-service Achei esse artigo muito útil.
JenonD
Apenas para mencionar, um serviço não deve estar acessando o DOM. Uma diretiva é o lugar para isso.
superluminary
1
@ superluminário, essa é realmente uma boa regra geral a seguir, mas também é bom saber por que uma certa regra está no ritmo e entender quando essa regra pode (ou até deve!) ser quebrada. Acredito que os modais / dicas de ferramentas e similares são uma exceção à regra. Em resumo: é preciso conhecer as regras, mas também entender o contexto em que elas se aplicam / não se aplicam.
precisa saber é o seguinte
29

É engraçado porque estou aprendendo o Angular e assistindo alguns vídeos do canal deles no Youtube. O palestrante menciona seu problema exato neste vídeo https://www.youtube.com/watch?v=ZhfUv0spHCY#t=1681 em torno da marca de 28:30 minutos.

Tudo se resume a colocar esse trecho de código específico em um serviço e não em um controlador.

Meu palpite seria injetar novos elementos pop-up no DOM e manipulá-los separadamente, em vez de mostrar e ocultar o mesmo elemento. Dessa forma, você pode ter vários pop-ups.

O vídeo inteiro é muito interessante de assistir também :-)

Bart
fonte
2
Misko é a semente da angular! (bwa haha). Sério tho. Considere suas palavras como a fonte definitiva para angular.
deck
14
  • Crie uma diretiva 'pop-up' e aplique-a ao contêiner do conteúdo pop-up
  • Na diretiva, envolva o conteúdo em uma posição absoluta div junto com a máscara div abaixo dele.
  • Não há problema em mover as 2 divs na árvore DOM, conforme necessário, dentro da diretiva. Qualquer código de interface do usuário está OK nas diretivas, incluindo o código para posicionar o pop-up no centro da tela.
  • Crie e ligue um sinalizador booleano ao controlador. Este sinalizador irá controlar a visibilidade.
  • Crie variáveis ​​de escopo vinculadas às funções OK / Cancel etc.

Edição para adicionar um exemplo de alto nível (não 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
fonte
$ watch em vez de 'watch'. Também não deveria ser 'pop-up' em vez de 'showPopup' scope.watch(showPopup, function(newVal, oldVal){?
precisa
14

Consulte http://adamalbrecht.com/2013/12/12/creating-a-simple-modal-dialog-directive-in-angular-js/ para obter uma maneira simples de fazer diálogo modal com o Angular e sem a necessidade de inicialização

Edit: Desde então, uso ng-dialog em http://likeastore.github.io/ngDialog, que é flexível e não possui dependências.

Nik Dow
fonte
1
Eu apenas fiz um sprint rápido com essa abordagem apenas para perceber que isso é ótimo para uma única abordagem pop-up / modal, no entanto, pense neste UX específico: digamos que um cliente esteja solicitando um item e a interface do usuário apresente uma pop-up de confirmação de pedidos (por isso, 'ocupamos' o pop-up de Adam com conteúdo). Agora clicamos em enviar ou comprar ou o que for desse pop-up, e há um erro pelo qual o usuário precisa alterar esse pedido na tela anterior. Quero exibir esse erro em outro pop-up no nível superior. Essa abordagem não facilita isso, eu não acredito.
11134 jusopi
3
É verdade, mas acho que mais de um pop-up pode ser uma interface do usuário ruim.
Nik Dow
Bem, o plugin é a resposta que eu estava procurando!
Andres Felipe
7

O Angular-ui vem com a diretiva de diálogo. Use-o e defina templateurl para qualquer página que você queira incluir. Essa é a maneira mais elegante e eu a usei no meu projeto também. Você pode passar vários outros parâmetros para o diálogo conforme a necessidade.

user2203937
fonte
5
O angular-bootstrap 0.6 em diante substituiu $ dialog por $ modal. Isso significa que você precisa mudar todo o código que está usando $ diálogo, uma vez que é obsoleto e escrevê-lo em $ modal
Mohammad Umair Khan