$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 property 从 skipHide
到 multiple
。因此,复制粘贴代码段时要小心。检查您的 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
它使用多个对话框预设或配置。
我想在另一个之上打开一个 $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
.
$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 property 从 skipHide
到 multiple
。因此,复制粘贴代码段时要小心。检查您的 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
它使用多个对话框预设或配置。