4

I am using the ng-include directive that will have a dynamic template and controller based on some variables in the scope. Currently I have a map like this.

$scope.map = {
    'key1': {
        controller: Ctrl1,
        templateUrl: 'tmpl1.html'
 }, 
'key12': {
        controller: Ctrl2,
    templateUrl: 'tmpl1.html'
    }
}

...

<div ng-include src="map[key].templateUrl" ng-controller="map[key].controller"></div>

However, I would like to discard this map and instead generate the templateUrl and controller via a string. The following returns the controller object but I need the function to be returned.

var ctrlObj = angular.module('moduleName').controller('ControllerName')

EDIT 1

To clarify:

However, I would like to discard this map and instead generate the templateUrl and controller via a string

Basically I would to set up 'sub-controllers' on a page a way so that it would be convention over configuration. A master controller that has information that all the sub-controllers would share: FooCtrl would be the 'master' controller while FooBarCtrl, FooBarSubCtrl would be sub-controllers. My goal would be to make a function that would resolve "Bar" to "FooBarCtrl" and from that grab the appropriate controller function.

3
  • can you use the 'ng-controller' directive at the top level element of your tmpl1 and 2.html instead of specifying it in the code? Commented Dec 4, 2012 at 17:05
  • 1
    What do you mean by "instead generate the templateUrl and controller via the string" ? Commented Dec 4, 2012 at 17:07
  • @RoyTruelove This is actually what I'm currently doing. I was just exploring a different option. Commented Dec 4, 2012 at 18:24

3 Answers 3

2

I don't see any trivial way of achieving this, however I can imagine two potential solutions:

  1. Modify ngInclude directive so that it takes the src expression, parses it to get the controller name (template Foo.html => controller FooCtrl) and sets the controller on the element like it is done in ngView (https://github.com/angular/angular.js/blob/master/src/ng/directive/ngView.js#L149):

    controller = $controller(current.controller, {$scope: lastScope});
    element.contents().data('$ngControllerController', controller);
    
  2. Create new directive e.g. "ajpaz-controller" that watches the src expression and links the controller to the element the same way as in point 1. The obvious advantage is that it can be done without modifying the original ng-include. It would work like this

    <div ng-include src="templateUrl" ajpaz-controller>
    

So you would have to only keep the current templateUrl in your parent controller. Hope that makes sense;)

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

Comments

1

I know it's been long since this question was posted, but it may be useful for others to know the correct answer...

If you've registered via the normal means, using the $controllerProvider:

app.controller('myController', function() {
    //blah, blah
});

You can use the $controller service to retrieve the controller function, it acts like a getter:

$controller('myController');

Of course, don't forget to inject it... ;-)

1 Comment

how to get $controller ?
0

From the following stackoverflow link. I believe it has the answer to this question.

Using Angular Controllers created with angular.module().controller()

Given:

angular.module('App.controllers', [])
    .controller('home', function () {
        $scope.property = true;
    }]);

Answer:

// Try using a string identifier.

routeProvider.when('/', {templateUrl: 'partials/home.html', controller: 'home'});

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.