$mdDialog stacked/nested 对话框,这可能吗?

$mdDialog stacked/nested dialogs, is it possible?

我想在另一个之上打开一个 $mdDialog。如果可能,有无限制的重叠对话框。

有什么想法吗?

不,现在不可能有​​多个 $mdDialog。老实说,我真的需要这个功能并尝试让它工作,但到目前为止没有成功。让我们希望他们在未来的版本中允许此功能。
虽然有讨论 here,但您可以在那里找到有用的东西。

注意:这不再是正确答案,与回答的时间段相反,请在下面查看更多答案。

Here 是嵌套对话框的解决方法。

想法是当第二个打开时保存第一个的状态,当第二个关闭时再次启动第一个对话框。

绝对不可能。*暂时。在某些情况下这是可以理解的,但也需要其他方式。 因此,我更喜欢使用自定义弹出对话框来实现相同的功能。 否则 md-dialog 会给工作带来痛苦。

  • 是的,我做到了,但如果需要 3 个嵌套,那么编写代码就可以了,但另一个无法理解。 您可以通过提供 scope 和 preservescope 参数来完成这项工作,然后管理何时关闭以及接下来打开哪个...brrrr ...

正如 Gabriel Anzaldo Alvarado 在评论中所写,您可以在这个 Plunker 上看到: http://plnkr.co/edit/Ga027OYU5nrkua3JxNRy?p=preview

此外,您可以添加一些css 类以获得相同的背景灰色叠加: 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;
}

更新:

从 Angular Material v1.1.2 开始,选项 skipHide 已替换为 multiple

更新:根据@Magnus,它从 v1.1.2

更新为 multiple

skipHide: true 添加到第二个对话框的选项对象。

这对我有用:http://webiks.com/mddialog-with-a-confirmation-dialog/

我用很少的努力和一些 angular 黑客技术就可以使用它。

为了清楚起见,我使用的是 Angular v1.5.3 & Angular Material v1.0.6.

对于以前的版本,如果您将 skipHide: true 添加到对话框定义对象,它将允许多个对话框。然后您的问题出现在取消按钮上,该按钮将关闭错误的对话框。

解决方案是调用 $mdDialog.cancel 我们想调用 $mdDialog.hide 因为它正确地解析了正确的对话框。我们可以装饰 $mdDialogProvider.

而不是确保您正确设置了每个实例,甚至确保第 3 方库也遵循这种模式

$provide.decorator

$provide.decorator(name, decorator);

Register a service decorator with the $injector. A service decorator intercepts the creation of a service, allowing it to override or modify the behavior of the service. The object returned by the decorator may be the original service, or a new service object which replaces or wraps and delegates to the original service.

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;
    });
});

以上将简单地用现有的有效隐藏方法替换取消方法。还设置全局默认值,以便在所有对话框中初始设置 skippHide。

胜者胜者!

Gabriel Anzaldo Alvarado 在我看来给出了正确的答案,正确答案已在 Plunker link 中分享。但应许多用户的要求,我添加了实际代码以防 link 将来不可用。

基本上,在使用 .show({}) 函数打开对话框时,添加选项 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
        }
      })
    }
  });
})();

上面的代码对我有用。

正如 Vincenzo 在另一个答案中指出的那样,在堆叠 mdDialogs 时,下面的对话框不会变灰,有一个 CSS 技巧可以解决这个问题:

更新

此答案适用于版本 1.1.1,从版本 1.1.2 开始,Material 团队 changed the propertyskipHidemultiple。因此,复制粘贴代码段时要小心。检查您的 Material 版本并相应地使用正确的 属性。

 $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();
        };
      }});

在视图中调用:

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

vm.addNewCustomer将是一个打开新对话框的函数

其实你可以使用mdPanels。小片段:

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
    };
});

并为 class 添加一些样式。 它不是模态的完全复制,但它的实现非常好,可以改进以完全复制。

是的,这是可能的,只需在调用 mdDialog 的地方添加“skipHide: true”。 就像:

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

更新:这是针对 angularJs (Angular 1)

从 Angular Material 版本 1.1.2 及以上:使用选项 multiple.

对以前的版本使用选项 skipHide

示例

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

skiphide 已弃用。请改用 multiple 键。请参阅文档 here

这是一个代码片段

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
            }
        })}

在最新的AngularJsMaterial对话框中,您可以找到这个解决方案: https://material.angularjs.org/latest/api/service/$mdDialog#multiple-dialogs

它使用多个对话框预设或配置。