AngularJS: how to split a long controller into modules?
Building my first angular app and I don't understand how to break the code into smaller chunks. I just have one long controller, but if I try to split the code into separate sections (controllers, services, etc.), all of a sudden the data is no longer bound to the view (i.e. I am updating the data but changes aren is shown in the view / browser).
t. I have a simple application that connects to the api to get a list of "Books", then displays the list and allows the user to navigate using pagination, or get more details for a single book, or update a book (edit / delete).
I would like to split the functions into separate controllers, for example:
- search . Controller: processes the checkout form, $ http to api;
- books (list): displays api search results;
- book (one) controller: each item in the list of books is a separate item with calls like "more" and "edit / delete";
- pagination controller: functions for next / prev through the list of books;
- Messages : Displays a success / error message when executing an action in the search, book, or pagination controllers.
The problem is that I don't know how to set this up because if I use services to store / output the "books" or "messages" model when I update that data through one of the controllers, this change does not automatically update the view (for example if I were to update the $ scope variable associated with the controller).
From what I understand, the $ scope variable in the view is updated automatically because it ng-controller="MyCtrl"
is region bound. But how will this work with the service? You are not using a tag ng-service
, right ...?
So let's say I have a searchController calling api get json from all books. I shoved this into booksService for storage. Then my booksController, which is responsible for updating the list of all books on the page, needs to load this bookService to get new data ... but how does it know that the data has been updated? How can I bind data from booksService via bookController to display new results in view?
And also how would I go about structuring the booksService - how do I get the searchController to transfer the new data (to update a constant variable that I can use for the model) and then how do I get the bookController to load into what new data? Do I need to create a call from booksService to PUSH new data to booksController, or if booksController has a PULL call to new data from booksService (and if so how does it know when it should PULL)?
Additionally, searchController and paginationController will make a GET call with a matching request with the same API (only the difference will be the $ page variable in the request). Should I use a "service" (or is it a factory?) To separate the $ http.get request?
Finally, what's the best way to structure all of these controllers / services in a folder / file structure? Should I aim to split each chunk into a separate * .js file? Should I use require.js to import files? In this case, it is one page of the website (where the site might have another other page like this page). If I split the code into separate files, should I group the files in the same folder on each web page? (ie if I add a "custom panel" page, all files will be stored in a separate folder from the "search books" page).
Sorry, I know I am asking a lot, but it would really help me think about the concepts involved in structuring an angular application correctly.
source to share
Place all your controllers this way in your controller.js file.
angular.module('starter.controllers', [])
.controller('SearchCtrl', function($scope) {
//do your search stuff
})
.controller('BookCtrl',function($scope){
})
.controller('PaginationCtrl',function($scope){
})
.controller('MessagesCtrl',function($scope){
});
//in your services.js file
angular.module('starter.services', [])
/**
* A simple service that returns some data.
*/
.factory('Search', function() {
var somedata="from service";
return {
sample: function() {
return somedata;
}
}
)};
you can call the factory service from any controller like
.controller('SearchCtrl', function($scope, Search) {
//get data from factory service
$scope.getdata=Search.sample();
})
also in your directive file
/*
its route map for the application
all the page navigation are done here
common for the application
*/
angular.module('app',[
'ui.router'
])
.config(['$urlRouterProvider','$stateProvider',function($urlRouterProvider,$stateProvider){
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home',{
url:'/',
templateUrl:'templates/home.html',
controller:'SearchCtrl'
})
.state('about',{
url:'/about',
templateUrl:'templates/about.html',
controller:'aboutCtrl'
})
}])
In your home.html you can read the data this way
<h2>{{$scope.getdata}}</h2>
Take a look at this link ( http://ionicframework.com/getting-started/ ) and try an example tabs
that simulates tab-based apps. Ionicframework with angularjs is better for such applications.
source to share