📜 ⬆️ ⬇️

Divide and conquer or how to make your application structured

As the old saying goes, how many people have so many code-writing styles. In today's article, I would like to reveal all the features of the correct configuration of the structure of AngularJS.
As in any application, we must have an entry point, the starting point from which our application will start. For frequent, I use just the app. In this file, which is not bad to call main.js, we will write the following code:

(function(ng) { var app = ng.app('app', []); // This should be your configuration like a routeProvider or etc. return app; })(angular); 

Also this module will include other modules in the future due to dependency injection.
What a start was made and it would not be bad to determine the structure of the application. We define certain entities of our application. Create folders: animations, controllers, factories, directives. In fact, now we will form the approach that is used in the Java package.
So, each of the directories we created should also contain its own entry points, again called main.js. For example, consider the directory with the controllers. In the main.js we write the following code:

 (function(ng) { var app = ng.app('app.controllers', []); return app; })(angular); 

As you can see, this module will be responsible for the implementation of controllers, which we will announce below. Now we can also include this module in the dependencies of the main module, which will look like

 (function(ng) { var app = ng.app('app', ['app.controllers']); // This should be your configuration like a routeProvider or etc. return app; })(angular); 

Now we describe a pair of controllers for our application to show how we can use. There are certain agreements with the name of the controllers, namely in the style of camel-case as a class. Let's create a file in the controllers MainCtrl.js directory, which will contain our controller logic. Its contents will be something like this:
')
 (function(ng) { var app = ng.app('app.controllers.MainCtrl', []); var MainCtrl = function($scope) { var localScope = { message: 'Message', list: [1,2,3,4,5,6] }; ng.extend($scope, localScope); }; app.controller('MainCtrl', ['$scope', MainCtrl]); return app; })(angular); 

Let's look at why this approach has the right to life. As before, we have declared a module that will be embedded in the dependencies of the main module of the controllers. The controller code itself is a separate function. After that, it is included as a controller and a full record of the controller declaration is used so that it is not broken after minimization and obfuscation. As you can see, a local variable is created in our controller as localScope. What is it done for? With a small number of variables in $ scope this is not particularly noticeable, but when there are a lot of them, the code becomes a bit unreadable and therefore I just took the technique of expanding the main $ scope through the angularjs extend method. As for me, this method is beautiful, concise and quite readable. We will also add our controller in dependence of our main module for controllers. Its code will be:

 (function(ng) { var app = ng.app('app.controllers', ['app.controllers.MainCtrl']); return app; })(angular); 

By this principle, we will build other dependencies for directives, factories, and so on. As for me, this approach gives a complete understanding of your application, its structure becomes immediately visible and very easy to upgrade by adding new controllers, services, directives, and so on.

In conclusion, I would like to talk a little about the controllers, or rather, about the new syntax “as”
If we do not want our variables or some functions to be observable. So we can fully use this approach:

 (function(ng) { var app = ng.app('app.controllers.MainCtrl', []); var MainCtrl = function($scope, $log) { var localScope = { message: 'Message', list: [1,2,3,4,5,6] }; this.nonObservableVar = { one: 1, two: 2 }; this.logger = function(obj) { $log.info(obj); }; ng.extend($scope, localScope); }; app.controller('MainCtrl', ['$scope', '$log', MainCtrl]); return app; })(angular); 

And in our view use this code:

 <div ng-controller="MainCtrl as main"> <div ng-click="main.logger('Test for a one value')">{{ main.nonObservableVar.one }}</div> <div ng-click="main.logger('Test for a two value')">{{ main.nonObservableVar.two }}</div> </div> 

What does this give us? Well, one of the advantages is that there are no angular watchers here. This speeds up our application, also allows nested controllers to use the context of parental controllers, which makes it possible to build our application more flexibly. This method is very easy to use. As before, we can also mix controller variables with $ scope variables so that we can use $ watch, $ apply, etc.

If interested, I will continue to write about angular and how to build beautiful and structured applications on it. In terms of writing an article about the use of angularjs with requirejs and beautiful features requirejs - packages.

Leave your comments in the comments.

PS: I wrote this post so that your application can be easily maintained in the future, so that those who will modify your application understand what and how you have there =)

Source: https://habr.com/ru/post/215273/


All Articles