Angular 1.3.15 overwriting varaible in third party directive

I decided to use the angular messenger package in my current project. There is one in his directive var = templateString

, which I would like to edit to a template of my choice.

I would like to know how to edit this line without messing up the source code. I've read a series of similar answers, but the closure I can find is to create a directive that overrides it entirely. I just want to edit the template string and leave in the existing code.

I am using angular 1.3.15

Directive

MessageCenterModule.
  directive('mcMessages', ['$rootScope', 'messageCenterService', function ($rootScope, messageCenterService) {
    /*jshint multistr: true */
    var templateString = '\
    <div id="mc-messages-wrapper">\
      <div class="alert alert-{{ message.type }} {{ animation }}" ng-repeat="message in mcMessages">\
        <a class="close" ng-click="message.close();" data-dismiss="alert" aria-hidden="true">&times;</a>\
        <span ng-switch on="message.html">\
        <span ng-switch-when="true">\
          <span ng-bind-html="message.message"></span>\
        </span>\
        <span ng-switch-default>\
          {{ message.message }}\
        </span>\
      </div>\
    </div>\
    ';
    return {
      restrict: 'EA',
      template: templateString,
      link: function(scope, element, attrs) {
        // Bind the messages from the service to the root scope.
        messageCenterService.flush();
        var changeReaction = function (event, to, from) {
          // Update 'unseen' messages to be marked as 'shown'.
          messageCenterService.markShown();
          // Remove the messages that have been shown.
          messageCenterService.removeShown();
          $rootScope.mcMessages = messageCenterService.mcMessages;
          messageCenterService.flush();
        };
        if (messageCenterService.offlistener === undefined) {
          messageCenterService.offlistener = $rootScope.$on('$locationChangeSuccess', changeReaction);
        }
        scope.animation = attrs.animation || 'fade in';
      }
    };
  }]);
      

Run codeHide result


Is it possible? What's the best way?

+3


source to share


2 answers


You can change the directive with AngularJS decoders like:



MessageCenterModule
  .config(function ($provide) {
    $provide.decorator('mcMessagesDirective', function ($delegate) {

      var directive = $delegate[0];
      //assign a new value to the template
      directive.template = 'My template';
      return $delegate;

    });
  });

      

+1


source


I am very sorry friend, you will have to redefine it.

YOINK! You are going to decorate it. Sounds a little gorgeous, but hey. He works.


Whenever you use $ provide # decorator , you get the original instance as local for injection by name $delegate

.

That way, you can keep what you want and throw away what you don't.

The first thing you need to do is figure out how the original implementation uses what you want to change so as not to break the whole thing.

Fortunately, the templateString you want to change is only used as directive.template

, so it should be pretty basic.



It will look something like this:

app.config(function ($provide) {
  /**
   * note the use of 'directivename' + 'Directive'.
   * Whenever you decorate a directive, you have to apply the 'Directive' suffix due to this: 
   * https://github.com/angular/angular.js/blob/master/src/ng/compile.js#L727
   */
  $provide.decorator('mcMessagesDirective', function ($delegate) {
    /**
     * We're getting the item at the first index here, 
     * because the $delegate of a directive isn't quite an 'instance' - 
     * it a collection of DDO (directive definition objects) that
     * go by the same name. 
     *
     * Yes, the $compileProvider allows multiple directives with the same name. 
     * We're interested in the first one in this case.
     */
    var dir = $delegate[0]; 

    /**
     * Modify the template of the directive. 
     * You can either hardcode this, or:
     * - Decorate the directive so as to pass the template in. 
     * - Fetch a template with $http. 
     * - Inject a string from a service, constant, provider, you name it.
     */
    dir.template = 'your_own_custom_templateString';

    /**
     * Return the full collection of directives (or rather, 'the $delegate'). 
     */ 
    return $delegate; 
  });
});

      

And you go, when you use mcMessages

it again , it will use the hardcode you just gave.


Links Moar!

+2


source







All Articles