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

2
  • You can go through this answer Commented May 2, 2016 at 10:02
  • Sorry but I can't understand the similarity between my problem and this reply. Commented May 2, 2016 at 10:28

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

4 Comments

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()
Then your code is enough. Setting the controller on parent of both the directive and button must do it.
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) plnkr.co/edit/fRs2YCDKTbpXyY0psDtE
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;
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?

1 Comment

Sadly, no, and with this code, the directive isn't even compiled.
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>

1 Comment

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.