Home Override AngularJS Directive $scope function
Reply: 0

Override AngularJS Directive $scope function

Shovas
1#
Shovas Published in 2018-01-12 15:07:49Z

How do I override an AngularJS Directive $scope function so that I can extend an existing directive and modify it without touching the original?

I have used decorators successfully to change the templateUrl, for example, but when there is an original directive $scope function I'm not sure how to override it in the decorated version.

The original directive works as expected and I see all debug statements but I'm not seeing expected debug statements when decorated.

In the code sample below, I've shown the original and decorated directive, and I hope to see decorated $scope.init() console.log() debug but I only see the original debug. I've also added the order of debugs I see below the sample code.

angular
   .module('app')
   .directive("postWidgetDir", function() {
     console.log('postWidgetDir()');
     return {
       restrict: 'E',
       priority: 9999,
       scope: {},
       templateUrl: 'app/views/postWidgetDir.view.html',
       controller: ['$scope', 'apiService', 'alertService',
         function($scope, apiService, alertService) {
           console.log('postWidgetDirController()');

           $scope.init = function() {
             console.log('postWidgetDirController().init()');
           };

           // Initialize
           $scope.init();

         }
       ],
       link: function(scope, element, attrs) { // Caution! Always stop background tasks (eg. timeouts, intervals) on-destroy to avoid memory leaks.
         console.log("link() in postWidgetDir()");
         element.on('$destroy', function() {
           console.log('$destroy() in postWidgetDir()');
         });
       }
     };
   });

 angular
   .module('app')
   .config(function($provide) {
     return $provide.decorator('postWidgetDirDirective', function($delegate, $controller) {
       console.log("$provide.decorator('postWidgetDirDirective')");

       // Original directive
       var directive = $delegate[0];

       // Override original directive properties
       directive.templateUrl = 'app/views/postWidgetDir_custom.view.html';

       // Extend original directive controller
       var controller = directive.controller;
       directive.controller = function($scope, $timeout) {
         console.log("directive.controller() in $provide.decorator('postWidgetDirDirective')");
         angular.extend(this, $controller(controller, {
           $scope: $scope
         }));

         // I don't see this console.log()
         $scope.init = function() {
           console.log("$scope.init() in directive.controller() in $provide.decorator('postWidgetDirDirective')");
           $scope.init();
         };
       };

       var link = directive.link;
       directive.compile = function() {
         console.log("directive.compile() in $provide.decorator('postWidgetDirDirective')");

         return function(scope, element, attrs) {
           console.log("link() return in directive.compile() in $provide.decorator('postWidgetDirDirective')");
           link.apply(this, arguments);

           // I don't see this console.log()
           scope.init = function() {
             console.log("scope.init() in link() return in directive.compile() in $provide.decorator('postWidgetDirDirective')");
             scope.init();
           };
         };
       };

       return $delegate;
     });
   });

Here is the actual console.log() debug output I see,

postWidgetDir()
$provide.decorator('postWidgetDirDirective')
directive.compile() in $provide.decorator('postWidgetDirDirective')
directive.controller() in $provide.decorator('postWidgetDirDirective')
postWidgetDirController()
postWidgetDirController().init()
link() return in directive.compile() in $provide.decorator('postWidgetDirDirective')
link() in postWidgetDir()
You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.333579 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO