覆盖AngularJS指令$ scope函数

时间:2018-01-12 15:07:49

标签: angularjs angularjs-directive

如何覆盖AngularJS指令$ scope函数,以便我可以扩展现有指令并修改它而不触及原始指令?

我已成功使用装饰器来更改templateUrl,但是当有一个原始指令$ scope函数时,我不知道如何在装饰版本中覆盖它。

原始指令按预期工作,我看到所有调试语句,但在装饰时我没有看到预期的调试语句。

在下面的代码示例中,我展示了原始和装饰指令,我希望看到装饰的$ scope.init()console.log()调试,但我只看到原始调试。我还在示例代码下面添加了调试顺序。

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

这是我看到的实际的console.log()调试输出,

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()

0 个答案:

没有答案