web-dev-qa-db-fra.com

$ mdDialog boîtes de dialogue empilées/imbriquées, est-ce possible?

Je veux ouvrir un $mdDialog au-dessus de l'autre. Si possible, multipliez les dialogues qui se chevauchent.

Des idées? 

25
Andrey

Non, il n'est pas possible pour l'instant d'avoir plusieurs $mdDialog. Honnêtement, j’ai vraiment besoin de cette fonctionnalité et j’ai essayé de la faire fonctionner, mais sans succès jusqu’à présent. Espérons qu'ils autoriseront cette fonctionnalité dans les prochaines versions. 
Bien qu'il y ait discussion ici , vous pouvez y trouver quelque chose d'utile.

NOTE: Ce n'est plus la bonne réponse, par opposition à la période de temps pendant laquelle la réponse a été donnée, regardez ci-dessous pour plus de réponses.

18
Salal Aslam

Gabriel Anzaldo Alvarado a donné la bonne réponse selon moi, la réponse correcte est partagée dans un lien Plunker . Mais comme de nombreux utilisateurs l’ont demandé, j’ajoute le code actuel au cas où le lien deviendrait indisponible à l’avenir.

En gros, lors de l’ouverture de votre boîte de dialogue à l’aide de la fonction .show({}), ajoutez l’option skipHide: true.

HTML

<body>
 <div ng-controller="AppCtrl as ctrl" 
    ng-cloak="" 
    class="virtualRepeatdemoVerticalUsage" 
    ng-app="MyApp">
  <md-content layout="column">
    <md-button ng-click="ctrl.moreInfo(1)">
       Open Dialog
    </md-button>
  </md-content>
 </div>
</body>

JavaScript

(function () {
  'use strict';

  angular
  .module('MyApp', ['ngMaterial'])

  .controller('AppCtrl', function ($interval, $mdDialog) {
    var vm = this;

    vm.moreInfo = function moreInfo(thing) {
      $mdDialog.show({
        controllerAs : 'dialogCtrl',
        clickOutsideToClose : true,
        bindToController : true,
        controller : function ($mdDialog) {
          this.click = function click() {
            $mdDialog.show({
              controllerAs : 'dialogCtrl',
              controller : function ($mdDialog) {
                this.click = function () {
                  $mdDialog.hide();
                }
              },
              preserveScope : true,
              autoWrap : true,
              skipHide : true,
              template : '<md-dialog class="confirm"><md-content><md-button ng-click="dialogCtrl.click()">I am in a 2nd dialog!</md-button></md-content></md-dialog>'
            })
          }
        },
        autoWrap : false,
        template : '<md-dialog class="stickyDialog" data-type="{{::dialogCtrl.thing.title}}"><md-content><md-button ng-click="dialogCtrl.click()">I am in a dialog!</md-button></md-content></md-dialog>',
        locals : {
          thing : thing
        }
      })
    }
  });
})();

Le code ci-dessus a fonctionné pour moi.

Comme l'a souligné Vincenzo dans une autre réponse, tout en empilant mdDialogs, les boîtes de dialogue ci-dessous ne seront pas grisées, il existe une astuce CSS pour résoudre ce problème: https://stackoverflow.com/a/38013682/366662

METTRE &AGRAVE; JOUR

Cette réponse fonctionne pour la version 1.1.1, à partir de la version 1.1.2, l’équipe Matériel a changé la propriété de skipHide en multiple. Soyez donc prudent lorsque vous copiez-collez l'extrait de code. Vérifiez la version de votre matériel et utilisez la propriété correcte en conséquence. 

21
Dorival

MISE À JOUR: Selon @Magnus, il a été mis à jour à multiple à partir de v1.1.2


Ajoutez skipHide: true à l'objet options du deuxième dialogue.

Cela fonctionne pour moi: http://webiks.com/mddialog-with-a-confirmation-dialog/

19
Vinod Patil

salut les gars voici une solution pour avoir des dialogues imbriqués: https://github.com/angular/material/issues/698

l'idée est que lorsque le second est ouvert, enregistrez l'état du premier et, lorsque le second est fermé, ouvrez à nouveau le premier dialogue.

6
gabrielAnzaldo

Comme Gabriel Anzaldo Alvarado a écrit dans le commentaire, il est possible, comme vous pouvez le voir sur ce Plunker: http://plnkr.co/edit/Ga027OYU5nrkua3JxNRy?p=preview

En outre, vous pouvez ajouter des classes CSS pour obtenir le même fond gris en surimpression: https://github.com/angular/material/issues/7262

._md-dialog-backdrop:nth-of-type(even) {
    z-index: 81;
}

._md-dialog-backdrop:nth-of-type(odd) {
    z-index: 79;
}

.md-dialog-container:nth-of-type(even) {
    z-index: 80;
}

.md-dialog-container:nth-of-type(odd) {
    z-index: 82;
}

METTRE &AGRAVE; JOUR:

Dans Angular Material v1.1.2, l’option masquer-masquer a été remplacée par multiple.

5
Vincenzo

skiphide est obsolète. Utilisez la touche multiple à la place. Voir la documentation ici

voici un extrait de code 

myCtrl.demoClick = function moreInfo(thing) {
        $mdDialog.show({
            controllerAs: 'dialogCtrl',
            clickOutsideToClose: true,
            bindToController: true,
            controller: function ($mdDialog) {
                this.click = function click() {
                    $mdDialog.show({
                        preserveScope: true,
                        multiple: true,
                        controllerAs: 'dialogCtrl',
                        controller: function ($mdDialog) {
                            this.click = function () {
                                $mdDialog.hide();
                            }
                        },
                        template: '<md-dialog class="confirm"><md-content>I am in a 2nd dialog!<md-button class="md-raised" ng-click="dialogCtrl.click()">Confirm!</md-button></md-content></md-dialog>'
                    })
                }
            },
            autoWrap: false,
            template: '<md-dialog class="stickyDialog" data-type="{{::dialogCtrl.thing.title}}"><md-content>I am in a dialog!<md-button class="md-raised" ng-click="dialogCtrl.click()">Click me to do something</md-button></md-content></md-dialog>',
            locals: {
                thing: thing
            }
        })}
3
Bob Sheehan

Dans Angular Material version 1.1.2 et ci-dessus: Utilisez l'option multiple .

Utilisez l'option skipHide pour les versions précédentes.

Exemple

$mdDialog.show({
    template: 'asdf'
    controller: "xyzController",
    multiple: true // Replace with "skipHide" on Angular Material 1.1.1 or before
})
3
HoffZ

J'ai obtenu ce travail avec très peu d'effort et un peu de piratage angulaire.

Pour clarifier les choses, j'utilise Angular v1.5.3 et Angular Material v1.0.6.

Avec les versions précédentes, si vous ajoutez skipHide: true à votre objet de définition de boîte de dialogue, plusieurs boîtes de dialogue seront autorisées. Votre problème vient ensuite sur le bouton d'annulation qui ferme la boîte de dialogue incorrecte.

La solution consiste plutôt à appeler $mdDialog.cancel, nous voulons appeler $mdDialog.hide car cela résout correctement la boîte de dialogue appropriée. Plutôt que de vous assurer que vous avez correctement configuré chaque instance, ou même de vous assurer que les bibliothèques tierces suivent également ce modèle, nous pouvons décorer le $mdDialogProvider.

$ Provide.decorator

$provide.decorator(name, decorator);

Enregistrez un décorateur de service avec l'injecteur $. Un décorateur de service intercepte la création d'un service, ce qui lui permet de remplacer ou de modifier le comportement du service. L'objet renvoyé par le décorateur peut être le service d'origine ou un nouvel objet de service qui remplace ou enveloppe et délègue au service d'origine.

angular.module('module').config(function($provide) {
    $provide.decorator('$mdDialog', function($delegate) {
        var methodHandle = $delegate.show;
        function decorateDialogShow() {
            var args = angular.extend({}, arguments[0], {
                skipHide: true
            });
            return methodHandle(args);
        }
        $delegate.show = decorateDialogShow;
        $delegate.cancel = function() {
            return $delegate.hide(null);
        }
        return $delegate;
    });
});

Ce qui précède remplacera simplement la méthode d'annulation, par la méthode de masquage existante et active. Définit également une valeur globale par défaut pour que skipHide soit défini initialement dans toutes les boîtes de dialogue.

Gagnant gagnant!

3
Shannon Hochkins

Oui c'est possible, ajoutez simplement "skipHide: true" à l'endroit où vous appelez mdDialog ...

$scope.xyz = function(anything) {
  $mdDialog.show({
    controller: "xyzController",
    skipHide: true,
    templateUrl: 'path-to-partial/xyzDialog.html',
    parent: angular.element(document.body),
    clickOutsideToClose: true
  })
}

2
 $mdDialog.show({
     parent: angular.element(document.body),
     templateUrl: 'template.html',
     clickOutsideToClose: true,
     fullscreen: true,
     preserveScope: true,
     autoWrap: true,
     skipHide: true,
     controllerAs: 'customDialog',
     controller: function ($mdDialog) {
        this.callNewDialog = function (dialogCallback) {
            dialogCallback();
        };
      }});

appel en vue: 

ng-click="customDialog.callNewDialog(vm.addNewCustomer)"

et vm.addNewCustomer sera une fonction qui ouvrira une nouvelle boîte de dialogue

2
Hubert Pietruczuk

En fait, vous pouvez utiliser mdPanels. Petit extrait:

return $q(function(resolve, reject){
         $mdPanel.open(Object.assign({
            hasBackdrop: true,
            zIndex: 85, //greater than modal and lower than autocomplete\select
            locals: Object.assign({
                onClose: resolve
            }, locals),
            template: getCommonTemplate(template, heading),
            bindToController:true,
            controller: 'PanelDummyController as $ctrl',
            panelClass: 'rl-modal-panel',
            position: $mdPanel.newPanelPosition()
                .absolute()
                .center()
        }))


 });


controller('PanelDummyController', function (mdPanelRef) {
    'ngInject';

    const close = () => mdPanelRef.close().then(() => {
        this.onClose(Object.assign({}, this));
    });

    this.$mdDialog = {
        cancel: close,
        hide: close
    };
});

et ajoutez un peu de style à la classe . Ce n'est pas une copie complète de modal, mais c'est une très bonne implémentation et pourrait être améliorée pour une copie complète.

0
Valery Kozlov

dans la dernière boîte de dialogue Matériau AngularJs, vous pouvez trouver cette solution: https://material.angularjs.org/latest/api/service/$mdDialog#multiple-dialogs

Il utilise plusieurs préréglages ou configurations de dialogue.

0
Patrik Laszlo