Reputation: 39394
I have the following Angular code:
var application = angular.module('Application', []);
application.controller('ImageController', function ImageController($scope, $http) {
$http.get('api/images').
success(function (data, status, headers, config) {
$scope.images = data;
}).
error(function (data, status, headers, config) { });
$scope.vote = function (image) {
$http.post('api/images/{key}/vote', { key: image.Key }).
success(function (data, status, headers, config) {
}).
error(function (data, status, headers, config) {
});
};
});
How can I have controllers in different files when they share the same application? I suppose I should use define the controller differently that: application.controller('ImageController', ...
I think I should remove the $http part from the controller, right? I was reading about Angular Factories and Services but I am not sure which to use.
My interpretation of a factory is something that delivers services on request. At least that is how is usually used in, for example, C#.
But in my example, how should I remove the $http part to a service / factory?
And how to inject it in the Controller?
Upvotes: 1
Views: 69
Reputation: 37701
1) You just call the module in the new file, but don't re-define it:
var application = angular.module('Application'); // no second parameter!
application.controller('newController', ...
Or, if the application
is a global, just omit the first line. Technically, you can have one controller per file, no problem.
Note: you must omit the second parameter in the module()
method, see Creation versus Retrieval
here: https://docs.angularjs.org/guide/module
2) Yes, those things are usually kept in services/factories:
factory
application.service('myService', function($http) {
return {
getStuff: function() {
return $http.get('api/images');
},
postStuff: function(image) {
return $http.post('api/images/{key}/vote', { key: image.Key });
}
}
});
controller:
application.controller('ImageController', function ($scope, myService) {
myService.getStuff()
.success(function (data, status, headers, config) {
$scope.images = data;
})
.error(function (data, status, headers, config) { });
$scope.vote = function (image) {
myService.postStuff(image)
.success(function (data, status, headers, config) {
})
.error(function (data, status, headers, config) {
});
};
});
Note that I had to inject the service as a dependency into the controller.
See the fully working version here (I added a fake json file, since we have no access to the API, of course). It shows the code in separate files, and how to interact with the service: http://plnkr.co/edit/rOG0XSxf2qE70Wyw1a8N?p=preview
Upvotes: 2
Reputation: 6820
1) If you want to split your code into separate files, then you probably want to create a separate module in each file. You can then add those modules as dependencies for your main Application module by listing their names inside the square brackets when you create the module. See example below.
2) This answer gives a good description of the difference between a factory and a service. Basically, you can do the same things with both; you just write them in different ways. You inject the factory/service the same way you inject anything else (like $http
or $scope
).
If you define a factory, it might look something like this:
MyFactory.js
(function() {
var application = angular.module('MyFactoryModule', []);
application.factory('MyFactory', function ($http) {
var myFactory = {
images: null
};
$http.get('api/images').
success(function (data, status, headers, config) {
myFactory.images = data;
}).
error(function (data, status, headers, config) { });
myFactory.vote = function (image) {
$http.post('api/images/{key}/vote', { key: image.Key }).
success(function (data, status, headers, config) {
}).
error(function (data, status, headers, config) {
});
};
return myFactory;
});
})();
Application.js
(function() {
// Notice how Application depends on MyFactoryModule
var application = angular.module('Application', ['MyFactoryModule']);
application.controller('ImageController', function ($scope, MyFactory) {
// Example of how you might use MyFactory:
MyFactory.vote(MyFactory.images[0]);
});
})();
Upvotes: 0
Reputation: 2685
The controller function takes a second argument of a function, this function ImageController can be defined anywhere, including another file.
Some things to keep in mind, you will want to define the $inject property with an array of the services you are injecting to ensure minification safety.
var application = angular.module('Application', []);
application.controller('ImageController', ImageController);
then somewhere else:
function ImageController($scope, $http) {
$http.get('api/images').
success(function (data, status, headers, config) {
$scope.images = data;
}).
error(function (data, status, headers, config) { });
$scope.vote = function (image) {
$http.post('api/images/{key}/vote', { key: image.Key }).
success(function (data, status, headers, config) {
}).
error(function (data, status, headers, config) {
});
};
}
ImageController.$inject(['$scope','$http'])
Alternately you could register your controller in the controller file, allowing you to include only the controllers needed for any given page, however I prefer to bundle my application's controllers as a whole and cache it. making where I wire the application up exist within one file, similar to DI configurations in other language ecosystems
Upvotes: 0