0

I try to make a custom directive (here a progress-bar). Here is its declaration in the HTML :

<body ng-app="progressBar" ng-controler="progressBarCtrl">
<pb widthb="20" heightb="100"></pb>
<button ng-click="setProgress(10)">set to 10</button>
</body>

And here my module declaration :

angular.module('progressBar', [])
//
// Directive that generates the rendered chart from the data model.
//
.directive('pb', function() {
  return {
    restrict: 'EA',
    templateUrl: "flowchart/progress-bar.html",
    replace: true,
    controller: 'progressBarCtrl',
    scope :{
     widthb: '=',
     heightb: '='
    }
  };
})
.controller('progressBarCtrl', ['$scope', function progressBarCtrl ($scope) {
 $scope.progress=60;
 $scope.setProgress = function (value) {
  if (value>100){
    value=100;
  }
  if (value<0){
    value=0;
  }
  $scope.progress=value; 
 };
}]);

Clicking on the button "set to 10" will never call the function.

Plunker

  • You can go through this [answer](http://stackoverflow.com/questions/36979126/call-controller-function-from-the-directive-in-angular-js/36979206#36979206) – byteC0de May 02 '16 at 10:02
  • Sorry but I can't understand the similarity between my problem and this reply. – Pierre Bonhoure May 02 '16 at 10:28

3 Answers3

0

Try this:

.directive('pb', function() {
  return {
    restrict: 'EA',
    templateUrl: "flowchart/progress-bar.html",
    replace: true,
    controller: 'progressBarCtrl',
    bindToController: {
      widthb: '=',
      heightb: '='
    },
    scope: true
  };
})

Does that let the setProgress() work?

rrd
  • 5,789
  • 3
  • 28
  • 36
0

you are doing typo in html, write ng-controller not ng-controler,

also it is useful if you try like that:

<html ng-app="progressBar">
  <body ng-controller="progressBarCtrl">
  <pb widthb="20" heightb="100"></pb>
  <button ng-click="setProgress(10)">set to 10</button>
  </body>
</html>
oguzhan00
  • 499
  • 8
  • 16
  • Thank you, as commented ranjith, now my problem is that the scope isn't shared and they both use a different instance of the controller. – Pierre Bonhoure May 02 '16 at 12:17
0

Answer form oguzhan00 should fix your issue.

But in this case you don't have to actually define ng-controller at body tag. From your code I think you are trying to create a controller for your directive. In that case you don't need ng-controller in html. When your directive gets evaluated, the controller will also be automatically instantiated. The only thing that you would need to do is move the button tag to your directive's templateUrl as the scope will be only in that html. That will also fix the issue.

Also it is better to use controllerAs syntax when you use angular controllers for directives because when the application is large there is high chance that we can get confused with scopes and hence using an alias name is always suggested.

Ranjith V
  • 134
  • 5
  • Thank you but is there a way to force the directive and my button use te same controller (and so the same scope) without putting the button in the template? My goal is to produce a progress bar component on which others components can call the setProgress() – Pierre Bonhoure May 02 '16 at 12:15
  • Then your code is enough. Setting the controller on parent of both the directive and button must do it. – Ranjith V May 02 '16 at 12:28
  • Well I would have loved that it was so simple, I guess I'm doing a big mistake somewhere but I can't figure out where, here is a plunker of my situation (i changed the value I want to modify but anyway the problem is the same) https://plnkr.co/edit/fRs2YCDKTbpXyY0psDtE – Pierre Bonhoure May 02 '16 at 13:03
  • Okay.. Here is your problem. There is a directive and a controller in your code and the "progress" variable is used in the template url of directive. So it will look at the scope of directive to get the value of progress but you are setting it in the scope of controller when the button is clicked. Just change the code of you directive as below restrict: 'EA', templateUrl: "progress-bar.html", replace: true, link: function(scope,elem,attr){ scope.$parent.progress = attr.progress; – Ranjith V May 02 '16 at 13:25