
Our most obscene and disgusting actions that go beyond all norms of morality and principles usually begin with the words “Why not?”.
In this post I will address the issues of designing an application on AngularJS, philosophy, its architecture, assembly, walk through various useful libraries and ready-made architectural patterns. To top it off, I will arrange a small Angular + Require.js + Grunt + Yeoman orgy, which I called
Angular-Super-Seed, or a slightly more modest
ASS generator .
So, if you plan to write an application on Angular, then why not?
')
Motivation
- "Treat people the way you would like them to do to you." Suddenly someone come in handy
- Learn something new both about yourself and about development in the comments.
- Popiar your application generator ASS .
What does the Angular application consist of?
Provided that the application on Angular does not consist of services, controllers, directives and templates?
That's right, the application on Angular consists of modules and only modules.
Ok, wise guy, what are the modules?
But modules, in turn, may already consist of services, controllers, directives, services, providers and templates.
Services
Services is perhaps the simplest component in terms of its application. What is it for? In most cases, the service is used as a model in MVC theory, that is, for working with data. For example, you can create a user service $ user to store data in cookies or local storage. Or $ api service - a wrapper for library $ http, which will interact with your server API. But the service can be processes that are executed by the background, and just libraries of objects, functions that you plan to use in different places of the code.
... .factory("$user",function($rootScope, $someLocalStorageService){ var user={ id:null, name:null, isAuthorized:false } if($someLocalStorageService.load("user"))angular.extend(user,$someLocalStorageService.load("user")); $rootScope.$watchCollection(function(){ return user; },function(user){ $someLocalStorageService.save("user",user); }); return user; });
In this example, the service is both a model and a background process that monitors the change of the object and immediately saves it in the local storage.
Now a few words about where you can work with these services.
Controllers
In the controllers. Abstracting how to call controllers and turn to the point. And their essence is simple to link the work of services. And only in this, although most often it seems that the controller serves to associate the display (/ layout / DOM / HTML) with the data. And in principle, initially it was. Previously, you could in the controller using this access to the data that is used in the template.
... .controller("SomeCtrl",function(){ this.var=" "; }); ... <p> {{var}}</p>
But the shop was quickly covered, and now, to access this data, you need a special service $ scope. Therefore, we write:
"controllers are a structural component that is used to implement the interaction between services .
"If I were a teacher taking an exam with a student, I would not say better. But, to be honest, in 99.99% of cases, the controllers will be used by you precisely in order to connect ui with the logic of data processing.
Directives
But for how to bind, these very data with the layout correspond directives. About the fact that working with DOM in Angular should be done only in directives a lot of words are said, so if you are asked the question "Is it possible to call jQuery in the controller," answer "Yes, of course," and when he turns around happy start to leave, coolly shoot the head.
What gusto directives? The fact that you can very easily bind logic and data to ui elements. In principle, if you set yourself such a goal, then you can completely forget about such a term as a selector.
What is a directive? Something tied to the DOM element. How tied? As tag, as tag attribute, as tag class.
And this, in my opinion, is the whole essence of the Angula. Routing, data-binding, frame - all this was already before the angules in different frameworks. But I have never met such compactness and simplicity of designing ui.
Assembly issue
Why is it needed? So that when you load a page on production, you do not have hundreds of connections to download project files, but ideally one. So that when developing there was no need for pens to register the added files.
For a long time in large projects and teams he was solved with the help of handwritten tools, now there are Grunt / Gulp plugins for this. And there are several aspects. The essence of these plugins is that all your scripts / styles are stitched together. So you need somewhere to write the rules / dependencies, etc., how to sew these files. It will be inconvenient to do this in the code of the files themselves, which means you need to create additional
package files . But that is not all. Obviously, this stitching should occur after editing the project, when you want to test the result. And here two options are either to update with pens, calling the appropriate command, or to make a so-called
watcher - a script that monitors all your files and builds. In principle, the option is not bad, but when working on a large project, you can get the expected performance problems.
Therefore, I am a supporter of
Require.js . Why? Well, firstly, the dependencies are written in the code, secondly, when developing the browser itself, it will load all the necessary files and the stitching is not needed, well, thirdly, when it comes to production, all your files will be compressed into one and, if you want, minified
Therefore, the question of assembly is a question that everyone decides for himself, whether it is necessary or not, and what tools to use. The main thing that plays a role in solving this issue is architecture.
About architecture
Here again, I remember that the application consists of modules. Therefore, when you plan the architecture of your application, you should estimate how many modules it will consist of. It can consist of only one module or vice versa, it can have a separate module for each page of the site. What does it depend on? First, from your desire to split even a small application into modules. Secondly, on the size of the application. To make it clearer, here is the condition.
(boolean) = (boolean) || (boolean)
Well and not unimportant will be how you are going to test your application. If you want to drive tests separately for controllers, services, directives, then it is clear that you will need to bring them into separate modules “App.controllers”, “App.services”, “App.directives”, etc.
But as far as architecture is concerned, it is always nice to look at how others are doing.
NGBP
LGBT , just, assumes that your project will consist of many modules. The application has a
main module , which describes the routing and other initial settings, and the rest of the logic is distributed
among the components .
What catches your eye? The fact that all your controllers, services, directives, etc. should be described in a single module file. And although I personally am an adherent of simplicity, but even in my opinion it will already be a bust. And this is in my opinion the main disadvantage of this template.
Angular-seed
In my opinion, great for small and medium applications.
The project consists, albeit formally, of several modules, but this is exactly the case when controllers, services and directives come together, so from an architectural point of view, we can assume that there is only one module.
The advantages are obvious - everything is simple, clear and compact. Cons, too - if you do a big project, in a large team, you will be cramped, in addition to the whole assembly and minification of the application is not provided.
Angular require-seed
If you like angular-seed, but you want to use require, then please
use . Pros, cons are the same as the Angular-seed. Is it possible that by using require.js it will be easier for you to compile your project, but this is if you use
require-optimizerAngular-super-seed
I, thinking about the architecture of the application, about what is missing and what else to offer to the community, came to
this result .
What is the feature? You can split your project into modules, or you can restrict yourself to the main one. In terms of storing controllers, services and directives, I went even further. All of them are stored in separate files. Moreover, for each directive a
separate template and a
separate style file are created .
Component modules are defined and described also
in a separate file .
The obvious disadvantage of this approach is that when creating each new controller / service / directive, it is necessary to perform a bunch of routine operations to declare them. That is, you want to create a new directive: create a directive file, a template file, a styles file. Not deadly, but podnadoest can. And here it is time to say
YO ASS!Yeoman
When I first visited the
Yeoman website, I did not appreciate the service chips. Well, you can create separate files for specific templates. Well, this is what I can configure in the editor.
But when I thought about what it would be good not just to create separate files, but also to perform some other operations, then I also looked closely at fellow foreman.
The result
is a generator like this .
We put Yeoman
npm install -g yo
We put the generator
npm install -g generator-ass
What is the buzz? In what you can do in your console like this:
yo ass
And you will have a new application in your folder. Well, then - more.
yo ass:page main
Automatically create a new template for the page, a style file, a controller and
connect it all to the router.
Create a module
yo ass:module first
The module is
ready and already
delivered on a turnkey basis .
And now create a directive in it
yo ass:module firstDirective
We answer the question, in which module and everything is ok.
I must say that there is not enough testing and mocks yet. All will be.
That's all, I hope someone will come in handy. Why not?