如何扩展/覆盖 Angular Material $mdDialog.show 中的默认选项?
Posted
技术标签:
【中文标题】如何扩展/覆盖 Angular Material $mdDialog.show 中的默认选项?【英文标题】:How to extend/overwrite default options in Angular Material $mdDialog.show? 【发布时间】:2016-09-17 17:31:36 【问题描述】:TL;DR:我需要一种方法来使用提供程序(与任何其他 Angular 模块一样 - a random example)覆盖提供我的 Angular 材质(尤其是在材质对话框中)提供的默认选项。
我一直在寻找一种方法来自定义默认值options Angular Material Modal,但没有任何可用的结果。
就像我在其他插件/模块上使用的一样,这种方式可以使用provider
来实现。查看材料的核心 (1.0.8) 我试图使用这样的setDefaults
方法设置选项(假设我只想暂时禁用背景):
app.config(['$mdDialogProvider', function($mdDialogProvider)
console.log($mdDialogProvider);
// ^ $get/addMethod/addPreset/setDefaults
var defaults =
options: function()
return
hasBackdrop: false
$mdDialogProvider.setDefaults(defaults);
]);
现在,当我检查 onComplete
回调上的选项时:
如您所见,hasBackdrop
选项已更新,但模式不再起作用,所以我想我遗漏了一些东西。
您知道如何以适当的方式扩展默认角度吗?
谢谢
UPDATE : 没有.setDefaults
活动的选项对象(de 初始状态)
注意:我从他们的核心 transformTemplate
复制并添加到我的默认对象中,但结果是相同的。我可以看到 DOM 更新了,控制台没有错误,但模式不可见。
【问题讨论】:
你能解释一下你最终想要达到的目标吗?制定任务,也许可以有一种更透明的方式来实现它然后修补原始服务 请检查我的更新。我只需要一种更新默认材质选项的方法。现在,假设我想删除所有模块的背景,我必须在每个show
显示实例上调用它,而不是添加 hasBackdrop: false
作为所有模式的全局选项
我现在明白了。在我看来,您可以通过创建一个模态工厂来实现这一点,该工厂将使用更新的属性包装角材料模态。我会尽力说明我的意思
我为此做了一种包装服务,但我很好奇是否可以使用似乎是 Angular 的“正确方法”的提供程序。我还将使用我的服务更新代码。无论如何,将其添加到答案中,它可以以比我更好的方式完成。
【参考方案1】:
当您想从第三方库更新现有功能时,您应该尝试使用装饰器模式并装饰服务方法。
Angular 在配置应用程序时提供了一种在providers
上使用decorators
的简洁方法:https://docs.angularjs.org/api/auto/service/$provide
$provide.decorator
$provide.decorator(name, decorator);
使用 $injector 注册一个服务装饰器。服务装饰器拦截服务的创建,允许它覆盖或修改服务的行为。装饰器返回的对象可能是原始服务,也可能是替换或包装并委托给原始服务的新服务对象。
您可以为$mdDialogProvider
编写一个装饰器来扩展.show
方法的功能,并将扩展的options
对象传递给它,如下所示:
.config(function ($provide)
// Decorate the $mdDialog service using $provide.decorator
$provide.decorator("$mdDialog", function ($delegate)
// Get a handle of the show method
var methodHandle = $delegate.show;
function decorateDialogShow ()
var args = angular.extend(, arguments[0], hasBackdrop: false )
return methodHandle(args);
$delegate.show = decorateDialogShow;
return $delegate;
);
);
我创建了一个带有 hasBackdrop: false
工作示例的代码笔,因此在调用$mdDialog.show()
时不会显示背景:http://codepen.io/addi90/pen/RaXqRx
【讨论】:
对此的一个小提示:var args = angular.extend(, arguments[0], hasBackdrop: false )
。我会更改顺序以确保模式特定选项将覆盖我的自定义默认值,因此将变为:var args = angular.extend(, hasBackdrop: false , arguments[0])
。同样对于更简洁的代码,可以在变量中定义具有默认值的对象:D
同意。但这是对解决方案的优化:)
不错的解决方案!如果对话框是从Preset
创建的,也许您需要检查arguments[0]._options
。【参考方案2】:
请在此处找到带有演示的 codepen:http://codepen.io/shershen08/pen/vGoQZd?editors=1010
服务的外观如下:
var dialogFactory = function($mdDialog)
var options = ;
return
create: function(conf)
var preset = $mdDialog.alert()._options; //get defaults
var newOptions = angular.extend(preset, conf, options);//extend with yours
$mdDialog.show(newOptions);
,
//toggle various props
setProp: function(prop, val)
options[prop] = val;
;
;
在控制器中你可以像这样使用它:
$scope.toggleBackdrop = function()
$scope.backdrop = !$scope.backdrop;
//here we change the state of the service internal var
dialogService.setProp('hasBackdrop', $scope.backdrop);
;
$scope.showDialogViaService = function(ev)
//here we fill in the needed params of the modal and pass to the service
var obj =
'title': 'title',
'content': 'content',
'ok':'Ok!'
;
dialogService.create(obj);
【讨论】:
以上是关于如何扩展/覆盖 Angular Material $mdDialog.show 中的默认选项?的主要内容,如果未能解决你的问题,请参考以下文章
包装或扩展 angular-material 组件,允许将未知属性传递给子组件
Angular Material mat-spinner 自定义颜色
Angular 9 - 删除 Angular Material Stepper 上的默认图标(创建)