0

Let's suppose I have several controllers, controller1, controller2, etc. and these all take similar data but perform very different tasks. An example of such a controller would be:

angular.module('myApp').controller('controller1', ['$scope', function($scope) {
    $scope.limit = undefined;
    $scope.answer = undefined;
    $scope.hasresult = false;

    $scope.run = function() {
        // Do some controller-specific stuff here...
    }
}]);

All the other controllers will instantiate limit, answer, hasresult and run. What this allows me to do is something like this:

angular.module('myApp').controller('controller_indexer', ['$scope', function($scope) {
    $scope.controllers = 
    [
        {
            index: 1,
            name: 'Some special name',
            result: 'Some results from {{limit}} --> {{answer}} here'
        }
    ];
}]);

Now, in my HTML file, what I'd like to do is this:

<div ng-app="myApp" ng-controller="controller_indexer">
    <div ng-repeat="x in controllers">
        <div ng-controller="controller{{x.index}}">
            <!-- do some stuff here -->
        </div>
    </div>
</div>

However, this approach results in an error like the one below:

The controller with the name 'controller{{x.index}}' is not registered.

Is there any way to deal with this error or get around it?

Gargaroz
  • 313
  • 9
  • 28
Woody1193
  • 7,252
  • 5
  • 40
  • 90
  • 1
    you can have a directive that [makes dynamic controllers](https://stackoverflow.com/questions/24762229/dynamic-ng-controller-name) – Aleksey Solovey Jul 12 '18 at 14:07

1 Answers1

1

As found here

mainApp.directive('ngDynamicController', ['$compile', '$parse',function($compile, $parse) {
  return {
      scope: {
          name: '=ngDynamicController'
      },
      restrict: 'A',
      terminal: true,
      priority: 100000,
      link: function(scope, elem, attrs) {
          elem.attr('ng-controller', scope.name);
          elem.removeAttr('ng-dynamic-controller');

          $compile(elem)(scope);
      }
  };
}]);

You can use it like this:

<div class="col-xs6 col-sm-5 col-md-4 col-lg-3" ng-repeat="box in boxes">
<div ng-include src="'/assets/js/view/box_campaign.html'" ng-dynamic-controller="box.type"></div>
</div>
Matheno
  • 4,112
  • 6
  • 36
  • 53
  • I don't see how this is a solution. At the moment, all it appears to do is replace your directive name with `ng-controller` and compile the result. Wouldn't this simply produce the same error I was seeing? – Woody1193 Jul 12 '18 at 14:37
  • @Woody1193 Looks like it might work. Did you try it? – JLRishe Jul 12 '18 at 14:47
  • He was missing the interpolation line; once I added that it worked. I updated his solution to reflect the changes – Woody1193 Jul 12 '18 at 15:10
  • @Woody1193 I'm not that familiar with `$compile` and `$interpolate`, but if `scope.name` contains the desired controller's name (as opposed to an angular expression like `controller{{ index }}` then I don't think there's a need to interpolate. – JLRishe Jul 12 '18 at 16:06
  • @JLRishe But that was the whole point of the question. `scope.name` necessarily contained an angular expression so interpolation was required. – Woody1193 Jul 13 '18 at 15:13