0

How to instantiate a custom controller from code and preserve scope inheritance. In other words I want to do something like this:

var controller = 'myCtrl';
var html = '<p>{{value}}</p>';
var validScope= $scope.$new({
    value : 'Hello, custom controllers'
}); // Or something like this to get valid scopes inheritance
$(document.body).append(instantiate(controller, html, validScope));

So i need two answers: how to instantiate custom controller and how to do it like angular do.

UPD. I've tried do it this way:

$compile('<div ng-controller="myCtrl">'+html+'</div>')(validScope);

Controller was instantiated. But placeholded values was not binded.

6
  • You have a typo, I think. myCtrlScopeValue vs myCtrlValue Commented Oct 28, 2013 at 1:01
  • Thanks, fixed. But i have no typo in my test code. Commented Oct 28, 2013 at 1:05
  • why do you want to do it this way? Where are you running this code also? If you do it from within a directive you can use angular to compile which will automatically instantiate controller Commented Oct 28, 2013 at 1:06
  • I have big list of items. Each item has to be edited with proper controller. Each controller should be loaded on demand because there is a lot of controllers and some of them has a lot of dependencies. So i wont to load all of them in a single page. Commented Oct 28, 2013 at 1:10
  • thread on angular docs site ( ngController) pointed to a google group post that will likely help you See very last entry. Since 1.2 was a major release recently, might be more ability to do what you need now also Commented Oct 28, 2013 at 1:36

2 Answers 2

1

I do not know the context of where you are trying to all this controller from but I am going to assume you are wither in another controller, a service, or a directive.

The code below will show how to create a controller from a service. The example may cover more than what you would need to do but this is a pattern that will work.

Create an abstract controller, this sets the constructor parameters of the controller and insulates the rest of the dependencies.

module.factory('AbstractCtrl', ['dependencies...', function (dependencies...) {
    var ctrl = function($scope) {
           // Do controller setup.
    };

    return ctrl;
}]);

Now create a controller implementation based on the abstract

module.controller('CtrlImpl', ['$scope', 'AbstractCtrl', function ($scope, AbstractCtrl) {
    // Initialize the parent controller and extend it.
    var AbstractCtrlInstance = new AbstractCtrl($scope);
    $.extend(this, AbstractCtrlInstance);
    // … Additional extensions to create a mixin.
}]);

Now that you have a controller with a minimally defined constructor to create an instance of the controller you just need to call inject the $controller and do the following:

$controller('CtrlImpl', {$scope: $scope}));
Sign up to request clarification or add additional context in comments.

1 Comment

Interest solution. But i need to bind new controller instance to new DOM node.
1

I think that the best approach is to expose a function on the scope for retrieving your controller. (ngController can take a string or a function) Lets say you have different values which need different constructors... something vaguely like this:

<div ng-repeat="item in items">
  <div ng-controller="controllerFor(item)">
    // whatever
  </div>
</div>

That controllerFor function will know how to do the mapping for you. Hopefully, you can avoid using $compile all together.

2 Comments

Didn't know that controller could be evaluated. Thanks. It's good for controllers that you already load. But what's about controllers wich should be loaded with requirejs or other way?
I suppose if you are loading controllers via RequireJS, then you will need to write more complicated code. Seems like extra complication to me, to make the controller loading asynchronous, which is why I've never understood the benefit to using RequireJS in Angular.

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.