0

I'm trying to automatically create an instance of 'loadPlugCtrl' as may times as directive is used, but it's not working. You can see it's printing the same label twice where as they should be different. One more thing I noticed that in directive the command

console.log(ctrlInstName);

is getting executed only once. I have no idea what's happening here.

// Code goes here
angular.module('plunker', ['loadPlugin']);

function randomString(length) {
    chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    var result = '';
    for (var i = length; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)];
    return result;
}

angular.module('loadPlugin', [])
.directive("loadPlugin", ['$compile', function($compile){
  
  var ctrlInstName = "loadPluginCtrl_" + randomString(8);
  console.log(ctrlInstName);
  
  return{
    restrict: 'E',
    replace: true,
    controller: "loadPluginCtrl",
    controllerAs:ctrlInstName,
      link: function(scope, element, attrs) {
         
        scope.label = randomString(attrs.plug);
        var template = '<p>{{label}}</p>';
        var linkFn = $compile(template);
        var content = linkFn(scope);
        element.append(content);
        
      } // End link
    }; // End return
}])
.controller("loadPluginCtrl", ['$scope', function($scope) {
  // This controller should be instantiated as many times
  // as the directive is used in HTML.
}]);
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <link rel="stylesheet" href="style.css">
    <script data-require="[email protected]" src="https://code.angularjs.org/1.6.4/angular.js" data-semver="1.6.4"></script>
    <script src="script.js"></script>
  </head>

  <body>
    <p>Test</p>
    <load-plugin plug="15"></load-plugin>
    <load-plugin plug="20"></load-plugin>
  </body>

</html>

Let me explain you guys, what actually I am trying to do. I have n number of form templates stored on server along with their data in database. All most all of the features required to handle forms has been written in a controller. Let's say it's a base controller for all of them.

  1. Load the form template dynamically along with it's data using GET service.
  2. Automatically assign base controller's instance to it.

I am aware of the face that Angular is designed for SPA but my requirement is more of website like. I was wrong when thought I could achieve this using directive.

I would be glad if some one point me the right direction to do.

1
  • I am not sure I follow your logic. If you are using this controller in the router then you would have to update the router also. Otherwise you could turn this controller into a directive and $compile the inner directive into the controller multiple times or something along those lines. Commented Jul 18, 2017 at 23:51

2 Answers 2

1

A controller is instantiated each time when a directive is compiled, this is what it is for.

The problem is that you picked the wrong way to test this. Directive factory function is executed only once. That's why ctrlInstName never changes. All controller-specific code should be put to controller.

Dynamic controllerAs property is not possible and is a design mistake.

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

Comments

0

Each instance of directive will create a new controller instance.... but there is only one registration of the directive itself within the module

If you use controllerAs you want to assign values to the controller object not $scope and there is no benefit in creating a dynamic controller alias name:

angular.module('loadPlugin', [])
  .directive("loadPlugin", ['$compile', function($compile) {
    return {
      restrict: 'E',
      replace: true,
      controller: "loadPluginCtrl",
      //scope: {},
      template: '<p>{{$ctrl.label}}</p>',
      controllerAs: '$ctrl',
      link: function(scope, element, attrs, ctrl) {
          ctrl.label = randomString(attrs.plug);
      } // End link
    }; // End return
  }])
  .controller("loadPluginCtrl", ['$scope', function($scope) {
    var vm = this;
    // demonstrate that each use creates own instance of controller
    $scope.$watch(function(){
      return vm.label;
    }, function(nVal) {         
      if (nVal) {
        console.log('Label for this instance is:', nVal)
      }
    })
  }]);

DEMO

Comments

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.