2

How to set ng-controller as an expression from the $scope?

According to the documentation:

ngController – {expression} – Name of a globally accessible constructor function or an expression that on the current scope evaluates to a constructor function.

But how to evaluate scope expression as a controller for controllers that have been registered with module .controller?

For example:

Layout:

<div ng-controller="myExpr"></div>

JavaScript (define controller):

app.controller('myCtrl', ['$scope', '$timeout', function () { ... }];

JavaScript (parent scope):

$scope.myExpr = ...;

What should be in myExpr to use myCtrl as a controller via expression?

I've tried $controller('myCtrl')... not working...

P.S. If controller has been defined via globally accessible function.. it's possible to provide it as myExpr. But what to do if it has been defined so?

9
  • app.controller('myCtrl', [...]) returns a result that can be assigned to a variable and that could be assigned to the scope expression. That said, I fail to understand why you would want to do such a thing... Commented Jun 27, 2013 at 13:30
  • If you want to reuse functionality of one controller inside another controller, you are better off to refactor the stuff you need into a service that can be injected in all controllers. Commented Jun 27, 2013 at 13:33
  • I would like to use the same controller, but it should work with different services. For example we have a controller and inside it we send request to some API endpoint (via service), but inside of other view - same things, but endpoints is another.. Commented Jun 27, 2013 at 13:37
  • @callmekatootie When I try to save result into variable and assign it to scope expression.. I've gotten and error: Error: Argument 'ctrl' is not a function, got Object You could try: jsbin.com/otakaw/8/edit Commented Jun 27, 2013 at 13:44
  • I would avoid putting controllers as global variables, it just encourages people to be lax with their dependencies. The method you are using to define it is just fine. That saidm I am not quite sure I follow what you want to do. You want a controller, and inside that controller you want another controller that the first controller can switch out via a variable. Is that it? And if it is, is there a special reason why you can't use routes and ng-view? Edit: Never mind, saw the js bin now. I'll take a look. Commented Jun 27, 2013 at 13:58

1 Answer 1

1

The expressions that ng-controller accept are a bit wierd. So you can do this by writing your controller slightly differently (but read below as for why you probably don't want to).

function myCtrl($scope) {
  $scope.value = 'Stuff';
}

This is a controller and will work like normal for this case. Like in this example: http://jsbin.com/ubevel/2/edit

So why not do it?
First of all this is not a good way to define things from a testing perspective. Secondly, this allows you to set the controller dynamically on load but it won't allow you to change things after that. If you change the value of myExpr after the page has loaded the controller will not change.

So what to do?
I would highly suggest looking at using a service instead. Swap out your actions by supplying your outer controller with a service that you then change in the same manner you are now trying to change the inner controller. So something like: http://jsbin.com/ubevel/5/edit

This service can be swapped out on the fly, changing it will change the actions that are available in the scope.

You could also use an include, but this would result in duplicate html. I personalty am fine with this since I am against reusing html for two different types objects (sooner or later you want to change one but not the other and it becomes a mess). But a lot of people would object to that.



An extra note: There are probably nicer ways to do it with controllers, I probably haven't looked at all angles, but I just don't think controllers are the right tool for this case.

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

1 Comment

Good points. But it's not what I really want. I've temporary solved this issue with ng-include directive and copy-pasting of my html-code for the ng-repeat item. Real question is: how to use expressions for ng-controller directive with controllers that have been declared as module.controller('ctrl', [/** dependencies */]);. But two answers could be used as a tricky way to achieve the goal. P.S. if AngularJS has this feature, and that mean authors allow us to do that in some cases... maybe even for my goal :)

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.