Balu Krish
Balu Krish

Reputation: 53

How to call a controller function from angular directive

I want to call controller function from directive. Here is the fiddle. I have a sayHello() function in controller. And I want to call that function from angular directive. If i wall like scope.sayHello();

scope.sayHello is not a function

I am getting like the above in console.

Upvotes: 0

Views: 78

Answers (3)

asarenski
asarenski

Reputation: 46

I changed your directive a bit, but this is how you get that sort of functionality. FIDDLE

If you're interested in AngularJS I would highly recommend the John papa styleguide. https://github.com/johnpapa/angular-styleguide

It will get you using syntax like controllerAs and will help make your code cleaner.

HTML

<body ng-app="myApp" ng-controller="MainCtrl">
    <div>
      Original name: {{mandat.name}}
    </div>
    <my-directive mandat="mandat"></my-directive>
</body>

JS

var app = angular.module('myApp', []);
app.controller('MainCtrl', MainController);

function MainController($scope) {
  $scope.mandat = {
    name: "John",
    surname: "Doe",
    person: { id: 1408, firstname: "sam" }
  };
}

app.directive('myDirective', MyDirective);

function MyDirective() {
  return {
    restrict: 'E',
    template: "<div><input type='text' ng-model='mandat.person.firstname' /><button ng-click='updateparent()'>click</button></div>",
    replace: true,
    scope: {
      mandat: "="
    },
    controller: function($scope) {
      $scope.updateparent = function() {
        $scope.mandat.name = "monkey";
      }
    }
  }
}

Upvotes: 0

Alexander Nied
Alexander Nied

Reputation: 13678

The Angular directive's link function has arguments for both scope and controller -- if the method you want to call is directly on $scope in your controller you can just call it off of the scope arg-- if you are using controllerAs syntax (which I would recommend as it is a recommended Angular pattern) you can call it off the controller argument.

So, for your specific case (methods directly on $scope) in your directive return object you add a property link:

link: function (scope, iElement, iAttrs, controller, transcludeFn)
    scope.sayHello();
}

link runs once at directive creation-- if you want the scope or method to be available outside of that for some reason, assign it to a variable defined at the top level of the module.

Upvotes: 0

frosty
frosty

Reputation: 21762

To get your alert in your fiddle to fire, all I had to do what add the person into your template. You had the updateparent="updatePerson()", and you just needed to pass the person in that call, like this: updateparent="updatePerson(person)". Then your alert fired.

The reason for this is that you need to state in the template all of the parameters that you are passing in to the function. Since you call it like updateparent({person: mandatePerson}), you have to put the key person into your template that it will be called with that param. They have to match.

Upvotes: 1

Related Questions