5

I am developing an application using angularJs and nodejs. Am struck at setting the name of the controller to the value of a variable from main controller. To explain it better, my index.html looks like this :

        <tbody ng-repeat="group in groups">

        <tr ng-repeat="member in group.members" >
            <td rowspan="{{group.members.length}}" ng-hide="$index>=0">
            </td>

            <td>{{member.taskName}}</td>
            <td><div class={{group.colorMe[0]}}>{{member.env}}</div>
                <button class="btn btn-info" ng-controller="member.taskName" ng-click="test( member.taskName , 'env', group.colorMe[0])">Sanity</button>
            </td>

And my main Controller looks like this where the groups are defined as this :

  var tasks =['task1','task2','task3','task4','task5'];

      for(i=0;i<tasks.length;i++)

    {

    var group = {
                  "id" : i+1,
                  "members" : [{
                      "taskName":tasks[i].toUpperCase(),
                      "env1":versionMap["env1"+tasks[i]],
                      "env2":versionMap["env2"+tasks[i]],
                      "env3":versionMap["env3"+tasks[i]]

                  }]
                };
              $scope.groups.push(group);
              }

Now when i click the button , I should be direcrted to a particular controller and this controller name needs to be set dynamically to member.taskName . Can someone please help me with this?

Nagireddy Hanisha
  • 1,290
  • 4
  • 17
  • 39

1 Answers1

2

You need to add some extra logic to your service. So it will require new dependencies such as: $controller, $compile, $root$scope or $scope. And optional one $templateCache. Templates are optional as well.

DEMO JSFiddle

Dynamic controller service:

var controllerTemplate = $templateCache.get(params.templateUrl); // getting inline template string

var templateScope = $rootScope.$new(true); // creating new scope for future controlelr
var templateCtrl = $controller(dynamicControllerName, { // creating controller
     $scope: templateScope // locals stuff that inject in controller           
});

var dynamicControllerElement = angular.element(controllerTemplate); // wrapping template into element

dynamicControllerElement.children().data('$ngControllerController', templateCtrl); // inject controller into element

var compiled = $compile(dynamicControllerElement)(templateScope); // compile all together

$('.container').html(compiled); // putting compiled into DOM (jQuery example) 

More specific code for you:

Directive

 app.directive('dynamicControllerButton', function(dynamicControllerService){
    return {
      restrict: 'E',
      scope: {
         controllerName: '='
      },
      template: '<button class="btn btn-info">Sanity</button>', //added this comma
      link: function(scope, elem, attrs) {

           dynamicControllerService.createController(scope.controllerName, elem); // we passing also element;

    }

  }

})

Service

app.service('dynamicControllerService', function($rootScope, $controller, $compile){

     this.createController = function(dynamicControllerName, element) {

    // all that stuff in example above

      element.html(compiled); // adding compiled controller in element example ;

     }

})

HTML

    <tr ng-repeat="member in group.members" >
        <td rowspan="{{group.members.length}}" ng-hide="$index>=0">
        </td>

        <td>{{member.serviceName}}</td>
        <td><div class={{group.colorMe[0]}}>{{member.env}}</div>
            <dynamic-controller-button>  data-controller-name="dynamic_set_controller" ng-click="test( member.serviceName , 'env', group.colorMe[0])"></dynamic-controller-button>
        </td>

I hope it will help

Leguest
  • 2,097
  • 2
  • 17
  • 20
  • What is a controller service? Where do I need to plug in that code? – Nagireddy Hanisha Apr 28 '17 at 06:05
  • Thanks for the detailed answer. Will try this out. :) – Nagireddy Hanisha Apr 28 '17 at 06:10
  • I could not follow how the value of the controller-name is being set and also, $controller, $compile, $root$scope or $scope, $templateCache that you suggested, should all 5 of these be in the main controller or in my nested controller that I am setting? – Nagireddy Hanisha Apr 28 '17 at 06:54
  • 2
    No they being set only in `dynamicControllerService `. `controller-name` passed into directive `dynamicControllerButton `, and then passed to service method `createController` – Leguest Apr 28 '17 at 07:02
  • Thanks again. So, since I needed controoler-name as taskName(I updated the question for better understanding of others), in my case it should be data-controller-name="member.serviceName" (member.taskName in updated question). Also, just to update you about the progress, I have incorporated your answer in the code, and my getting an error saying var controllerTemplate = $templateCache.get(params.templateUrl); trying to figure out this, it says params not defined. – Nagireddy Hanisha Apr 28 '17 at 07:20
  • 2
    Yes, you are right. As I said tempates are optional, so you could do something like `var controllerTemplate = ''. And don't even use `$tempalteCache` at all – Leguest Apr 28 '17 at 08:01
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/142892/discussion-between-nagireddy-hanisha-and-leguest). – Nagireddy Hanisha Apr 28 '17 at 09:27