Skip to content Skip to sidebar Skip to footer

Angularjs Override Directive Controller Function

Here is the problem. I have some 3rd party directive called main-directive. app.directive('mainDirective', function() { return { scope: { foo: '&' // attrs

Solution 1:

Ok, I have done some research and it turns out that there can be several approaches there

Scope inheritance

Since child-directive is not creating own scope it just creating new methods at parent-directive parent scope. So we can modify attributes during compile and specify overridden foo method.

app.directive('parentDirective', function() {
  return {
    scope: {
      fooImpl: '&?',
      // lots of attrs
    },
    controller: function($scope) {

      $scope.foo = function() {
        if ($scope.fooImpl) {
          return$scope.fooImpl();
        }
        return"not overrided";
      }

    },
    template: '<div class="some-styling"><main-directive foo="foo()"></main-directive></div>'
  }
});

app.directive('childDirective', function() {

  return {
    scope: false,
    require: 'parentDirective',
    controller: function($scope) {

      $scope.foo = function() {
        return"overrided";
      }

    },
    compile: function(element, attr) {
      attr.fooImpl = "foo()";
    }
  }
});

Here is the DEMO1

Add to isolated scope

Angular provides special function. That can get isolated scope from element. So we can override our method during linking phase.

app.directive('parentDirective', function() {
  return {
    scope: {
      fooImpl: '&?',
      // lots of attrs
    },
    controller: function($scope) {

      $scope.foo = function() {
        if ($scope.fooImpl) {
          return$scope.fooImpl();
        }
        return"not overrided";
      }

    },
    template: '<div class="some-styling"><main-directive foo="foo()"></main-directive></div>'
  }
});

app.directive('childDirective', function() {

  return {
    scope: false,
    require: 'parentDirective',
    link: function(scope, element, attr) {
      var innerScope = angular.element(element[0]).isolateScope();
      innerScope.foo = function() {
        return"overrided";
      }
    }
  }
});

Here is the DEMO2

Controller method

If we use controllerAs syntax. That means we exposing controller object variables as a scope. We can override function in child directive during linking phase.

app.directive('parentDirective', function() {
  return {
    scope: {
      fooImpl: '&?',
      // lots of attrs
    },
    controller: function($scope) {

      var vm = this;

      vm.foo = function() {
        return"not overrided";
      }

    },
    controllerAs : 'vm',
    template: '<div class="some-styling"><main-directive foo="vm.foo()"></main-directive></div>'
  }
});

app.directive('childDirective', function() {

  return {
    scope: false,
    require: 'parentDirective',
    link: function (scope, element, attr, controller) {

       controller.foo = function() {
        return"overrided";
      }


    }
  }
});

Here is the DEMO3

Transclusion

Practically you can do the same thing with seperate parent and child directive and using transclusion. But anyway it would be combination of above approaches. Thanks for "Extending an existing directive in AngularJS"

Post a Comment for "Angularjs Override Directive Controller Function"