-2

Say I have a controller:

app.controller('HomeCtrl', Com.Xyz.ModuleHome.HomeController);

Com.Xyz.ModuleHome.HomeController is a controller function which has parameters like $scope, $window, $timeout, $http, ... these parameters are injected by AngularJS.

But I want to pass some parameters to the controller when it is registered. This is because my controllers are loaded from different domains by RequireJS, now I want to a controller to know where itself is from.

var myVar = jsFileUrl;  // jsFileUrl is provided by RequireJS

// I wish the code looks like below
app.controller('HomeCtrl', Com.Xyz.ModuleHome.HomeController, myVar);

// AngularJS will inject a $controllerContext representing controller itself
function Com.Xyz.ModuleHome.HomeController($controllerContext, $scope) {
    $scope.controllerJsFileUrl = $controllerContext.Argument;     
}

Is it possible? Maybe there is something I didn't know.

I know a service can do it, but I don't want the controller to depend on a special service name. In the future I may move the controllers to somewhereelse.

Zach
  • 5,715
  • 12
  • 47
  • 62
  • 1
    This might be helpul: http://stackoverflow.com/a/18191623/1488993 – Doon Sep 11 '15 at 02:50
  • Why try to go against the framework? Dependency injection is a great thing. Perhaps your design could be reworked :) – Sunil D. Sep 11 '15 at 04:01
  • No, I'm not against the framework. I just wish to get more information about the controller itself. – Zach Sep 11 '15 at 05:50

1 Answers1

1

Since you are looking for the anti-pattern, you could try using function.bindand pass the argument in the bound function. This will let the value of myVar to be passed in as first argument when the constructor is invoked (everytime).

app.controller('HomeCtrl', Com.Xyz.ModuleHome.HomeController.bind(null, myVar));

var app = angular.module('app', []);
var myVar = 1234;



function Ctrl(myVar, $q, $http) {
  console.log(arguments);
}


app.controller('ctrl', ['$q', '$http', Ctrl.bind(null, myVar)]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">

</div>

The above approach though short is tricky because you can no longer use controller instance as this as it would not the controller instance anymore instead it would be window. Another way is to create a dummy wrapper for the controller and new up the actual constructor.

.controller('ctrl', ['$q', '$http', function($q, $http) {
    return new Ctrl(myVar, $q, $http);
  }
]);
PSL
  • 123,204
  • 21
  • 253
  • 243
  • Thank you very much. Learned something I don't know. :) – Zach Sep 11 '15 at 03:08
  • @Zach You are welcome. But you need to be careful doing this if you are using controller instance `this` as it wont be the instance instead would be global context. – PSL Sep 11 '15 at 03:10
  • I just tested, however, other parameters, e.g. $scope are undefined. I use the static injection: $inject = ['$scope', '$rootScope', '$routeParams', '$http', '$window', '$timeout']; – Zach Sep 11 '15 at 03:18
  • @Zach that is another caveat you cant use $inject as well, it will work only with array annotation. – PSL Sep 11 '15 at 03:19
  • Thank you any way. But I just don't want to repeat the parameters of the function. – Zach Sep 11 '15 at 03:24