Angular module dependency injection not working as expected

时间:2017-06-15 09:57:33

标签: javascript angularjs node.js

So I am having troubles with managing dependencies for my node app. The structure is the following

app.js

var app = angular.module('myApp', ['myController', 'myFactory', 'rzModule', 'chart.js', 'myService', 'selector']);

myController.js

var app = angular.module('myApp', ['chart.js', 'rzModule', 'selector']);
app.controller('myController', function($scope, $http, $rootScope, myFactory, mySecondService){ ... }]);

myFactory.js

angular.module('myApp').factory('myFactory', function($http, $rootScope){ ... });

myService.js

angular.module('myApp').service('myService', function($http){...});

Above structure works, the app runs as expected. However I don't think what I am doing in myController.js is correct, because I now want to add another dependency and I can't figure out how to do so without the app crashing.

Question 1: In above myController.js, I think I am creating a new module instead of reusing the one from app.js, is that correct? If so, moving the 3 dependencies inline like the following results in "myController is not available":

var app = angular.module('myApp');
app.controller('myController',['chart.js', 'rzModule', 'selector', function(...)

Why does this not work? According to the documentation it should.

Question 2: I want to add angular-moment to the myController. The instructions say I should add 'angularMoment' as dependency to the app.js, and then 'moment' to the controller dependencies. If I do so and add 'moment' inline like in Question 1, I am getting again the "myController is not available" error.

3 个答案:

答案 0 :(得分:2)

So before answering your questions quick thing as you proceed with angularjs, modules need to be injected into the app not into the controller, so any module to be included need to be injected in the app.

var app = angular.module('myApp', [<all modules comma separated>]);

Similarly controller can have all those dependencies which are either linked to the myApp(like services, factories and others) and those services which are defined in modules which are injected into myApp

you cannot inject controllers, services in myApp only modules can be injected there

Question1

var app = angular.module('myApp', ['chart.js', 'rzModule', 'selector']);
app.controller('myController', function(...)

this shold work and using this it not meant you are creating any new app

Question2

var app = angular.module('myApp', ['angularMoment']);
app.controller('myController', ['moment', function(...)

like this you can use moment object.

答案 1 :(得分:1)

As Satpal has said

app.controller('myController',['chart.js', 'rzMo

Is the way to go, or a cleaner way to write this would be to do something like this.

angular.module('myApp').controller('myController');

myController.$inject = ['$scope', '$http', '$rootScope', 'myFactory', 'mySecondService']

function myController($scope, $http, $rootScope, myFactory, mySecondService){}

The reason myController is not available with the fixes is that it's now you're not overwriting the main application module and it's looking for a module called myController which can't be found (as it's a controller and not a module). So remove 'myController' from var app = angular.module('myApp', ['myController'

I suggest for you to take a look at John Papa's Style Guide for AngularJS it can be helpful for writing clean code.

答案 2 :(得分:0)

Ans 1: Yes in the second case you are trying to define it again. To define an app use:

angular.module('myApp', [..list of dependancies...]);

Now if you want to define controllers on the previous module use

angular.module('myApp').controller();

Now comes injecting your 3 dependancies, move them to the top where you have defined your app.

Ans 2: You will have to inject angularMoment to you app and moment to your controller.

The best way to handle dependancy injection in angular is to use $inject. for example you controller will look something like

angular.module('myApp').controller('myController', myController);

myController.$inject = ['moment','$scope', '$http', '$rootScope', 'myFactory', 'mySecondService']
function myController(moment, $scope, $http, $rootScope, myFactory, mySecondService){
    //your controller code.
}

or else you can try the following as well

angular.module('myApp').controller('myController',['moment','$scope', '$http', '$rootScope', 'myFactory', 'mySecondService', function myController(moment, $scope, $http, $rootScope, myFactory, mySecondService){
    //your controller code.
}]);

The following will also work but not recommended;

angular.module('myApp').controller('myController',function myController(moment, $scope, $http, $rootScope, myFactory, mySecondService){
        //your controller code.
    });