最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to extendoverwrite default options in Angular Material $mdDialog.show? - Stack Overflow

programmeradmin1浏览0评论

TL;DR : I need a way to overwrite default options provided my Angular Material (especially on Material Dialog) using providers (like any other angular modules - a random example).

I have been looking for a way to customize defaults options Angular Material Modal but without any usable result.

Like I have used on other plugins/modules this way could be achieved using a provider. Having a look in the core of the material (1.0.8) I was trying to set options using setDefaults method like this (let say I just want to disable backdrop for moment):

app.config(['$mdDialogProvider', function($mdDialogProvider){
    console.log($mdDialogProvider); 
    // ^ $get/addMethod/addPreset/setDefaults

    var defaults = {
        options: function(){
            return {
                hasBackdrop: false
            }
        }
    }
    $mdDialogProvider.setDefaults(defaults);
}]);

Right now when I am checking the options on onComplete callback :

So as you can see the hasBackdrop option is updated, but the modal is not working anymore so I think I am missing something.

Do you have any idea how the angular defaults could be extended in a proper way?

Thanks

UPDATE : Options object without having .setDefaults active (de initial state)

Note : I have copied from their core transformTemplate and added in my defaults object, but the result is the same. I can see the DOM updated, console has no errors, but the modal is not visible.

TL;DR : I need a way to overwrite default options provided my Angular Material (especially on Material Dialog) using providers (like any other angular modules - a random example).

I have been looking for a way to customize defaults options Angular Material Modal but without any usable result.

Like I have used on other plugins/modules this way could be achieved using a provider. Having a look in the core of the material (1.0.8) I was trying to set options using setDefaults method like this (let say I just want to disable backdrop for moment):

app.config(['$mdDialogProvider', function($mdDialogProvider){
    console.log($mdDialogProvider); 
    // ^ $get/addMethod/addPreset/setDefaults

    var defaults = {
        options: function(){
            return {
                hasBackdrop: false
            }
        }
    }
    $mdDialogProvider.setDefaults(defaults);
}]);

Right now when I am checking the options on onComplete callback :

So as you can see the hasBackdrop option is updated, but the modal is not working anymore so I think I am missing something.

Do you have any idea how the angular defaults could be extended in a proper way?

Thanks

UPDATE : Options object without having .setDefaults active (de initial state)

Note : I have copied from their core transformTemplate and added in my defaults object, but the result is the same. I can see the DOM updated, console has no errors, but the modal is not visible.

Share Improve this question edited May 28, 2016 at 15:38 Aditya Singh 16.7k15 gold badges48 silver badges69 bronze badges asked May 20, 2016 at 12:34 stefanzstefanz 1,32613 silver badges23 bronze badges 4
  • can you explain a bit more what you're tryin to achieve in the end? fornulate the task, maybe there can be a more transparent way to achieve it then patcing the original service – shershen Commented May 23, 2016 at 14:54
  • Please check my updated. I just need a way to update default material options. Right now, let say, if I want to remove backdrop for all modules i have to call this on each show show instance, instead of add hasBackdrop: false as a global option for all modals – stefanz Commented May 24, 2016 at 7:14
  • I see now. It seems to me that you can achieve this with creating a modal factory that will wrap the angular material modal with updated properties. I'll try to make a plunk illustating what I mean – shershen Commented May 24, 2016 at 7:41
  • I have made a kind of wrapper service for this, but I were curious if I could using provider which seems to be "the right way" for angular. I m also going to update the code with my service. Anyway, add this in an answer, it could be done in a better way than mine. – stefanz Commented May 24, 2016 at 8:10
Add a comment  | 

2 Answers 2

Reset to default 21 +50

When you want to update an existing functionality from a third party library, you should try to use decorator pattern and decorate the service method.

Angular provides a neat way of doing this using decorators on providers while configuring the app: https://docs.angularjs.org/api/auto/service/$provide

$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.

You can write a decorator for $mdDialogProvider to extend the functionality of the .show method and pass it the extended options object like shown below:

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

I have created a codepen with a working example with { hasBackdrop: false } so that backdrop is not shown on calling $mdDialog.show(): http://codepen.io/addi90/pen/RaXqRx

Please find the codepen with the demo here: http://codepen.io/shershen08/pen/vGoQZd?editors=1010

This how service will look:

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

};

and in the controller you can use it like this:

$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);
      }
发布评论

评论列表(0)

  1. 暂无评论