如何扩展/覆盖Angular Material $ mdDialog.show中的默认选项?

时间:2016-05-20 12:34:57

标签: javascript angularjs decorator angular-material

TL; DR :我需要一种方法来覆盖使用提供程序提供的Angular Material(特别是在Material Dialog上)的默认选项(就像任何其他角度模块一样 - a random example)。

我一直在寻找一种自定义默认值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回调选项时的选项:

enter image description here

因为你可以看到hasBackdrop选项已更新,但模态不再起作用,所以我想我错过了一些东西。

您是否知道角度默认值如何以适当的方式扩展?

由于

更新:没有.setDefaults有效的选项对象(初始状态)

enter image description here

注意:我已从他们的核心transformTemplate复制并添加到我的默认对象中,但结果是相同的。我可以看到DOM已更新,控制台没有错误,但模态不可见。

2 个答案:

答案 0 :(得分:19)

如果要更新第三方库中的现有功能,应尝试使用装饰器模式并装饰服务方法。

Angular在配置应用时decorators使用providers提供了一种简洁的方法: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 }工作示例的codepen,因此在调用$mdDialog.show()时不显示背景:http://codepen.io/addi90/pen/RaXqRx

答案 1 :(得分:0)

请在此处找到带有演示的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);
      }