Scopul acestui ghid de stil este de a prezenta un set dintre cele mai bune practici și linii de ghidaj de stil pentru o aplicația AngularJS.
Acest cele mai bune practici sunt colecționate din:
- Codul sursă AngularJS
- Codul sursă al articolelor pe care le-am citit
- Propria mea experiență
Note 1: acest text este încă o schiță a ghidului de stil, scopul său principal este de a fi condus de către comunitate, astfel încât umplerea golurilor să fie apreciată de întreaga comunitate.
Note 2: înainte de a urma orice linie de ghidaj de stil din traducerile documentului din engleză, asigură-te că este adus la zi. Ultima versione a ghidului de stil pentru AngularJS este documentul în engleză.
În acest ghid de stil nu voi urma linii de ghidaj de stil comune pentru dezvoltarea în JavaScript. Acestea pot fi găsite în:
- Ghidul de stil pentru JavaScript folosit de Google
- Ghidul de stil pentru JavaScript folosit de Mozilla
- Ghidul de stil pentru JavaScript folosit de Douglas Crockford
- Ghidul de stil pentru JavaScript folosit de Airbnb
- Ghidul de stil pentru JavaScript folosit de Idiomatic
Pentru dezvoltare în AngularJS este recomandat Ghidul de stil pentru JavaScript folosit de Google.
În wiki-ul AngularJS de pe Github există o secțiune similară făcută de ProLoser, o poți verifica aici.
- German
- Spanish
- French
- Indonesian
- Italian
- Japanese
- Korean
- Polish
- Portuguese
- Romanian
- Russian
- Serbian
- Serbian lat
- Chinese
- Turkish
- General
- Module
- Controlere
- Directive
- Filtre
- Servicii
- Șabloane
- Rute
- Testare CLC
- i18n
- Performanță
- Contribuție
- Contributori
Deoarece o aplicație AngularJS are multe componente este cel mai bine să o structurezi într-o ierarhie de directoare. Există două metode principale:
- Crearea de diviziuni de nivel înalt bazate pe tipuri de componente și divizuni de nivel jos bazate pe funcționalitate.
În acest fel, structura directorului va arăta astfel:
.
├── app
│ ├── app.js
│ ├── controllers
│ │ ├── home
│ │ │ ├── FirstCtrl.js
│ │ │ └── FirstCtrl.spec.js
│ │ │ └── SecondCtrl.js
│ │ │ └── SecondCtrl.spec.js
│ │ └── about
│ │ └── ThirdCtrl.js
│ │ └── ThirdCtrl.spec.js
│ ├── directives
│ │ ├── home
│ │ │ └── directive1.js
│ │ │ └── directive1.spec.js
│ │ └── about
│ │ ├── directive2.js
│ │ ├── directive2.spec.js
│ │ └── directive3.js
│ │ └── directive3.spec.js
│ ├── filters
│ │ ├── home
│ │ └── about
│ └── services
│ ├── CommonService.js
│ ├── CommonService.spec.js
│ ├── cache
│ │ ├── Cache1.js
│ │ ├── Cache1.spec.js
│ │ └── Cache2.js
│ │ └── Cache2.spec.js
│ └── models
│ ├── Model1.spec.js
│ ├── Model1.js
│ └── Model2.spec.js
│ └── Model2.js
├── partials
├── lib
└── e2e-tests
- Crearea de diviziuni de nivel înalt bazate pe funcționalitate și divizuni de nivel jos bazate pe tipuri de componente.
Aceasta este organizarea:
.
├── app
│ ├── app.js
│ ├── common
│ │ ├── controllers
│ │ ├── directives
│ │ ├── filters
│ │ └── services
│ ├── home
│ │ ├── controllers
│ │ │ ├── FirstCtrl.js
│ │ │ ├── FirstCtrl.spec.js
│ │ │ └── SecondCtrl.js
│ │ │ └── SecondCtrl.spec.js
│ │ ├── directives
│ │ │ └── directive1.js
│ │ │ └── directive1.spec.js
│ │ ├── filters
│ │ │ ├── filter1.js
│ │ │ ├── filter1.spec.js
│ │ │ └── filter2.js
│ │ │ └── filter2.spec.js
│ │ └── services
│ │ ├── service1.js
│ │ ├── service1.spec.js
│ │ └── service2.js
│ │ └── service2.spec.js
│ └── about
│ ├── controllers
│ │ └── ThirdCtrl.js
│ │ └── ThirdCtrl.spec.js
│ ├── directives
│ │ ├── directive2.js
│ │ ├── directive2.spec.js
│ │ └── directive3.js
│ │ └── directive3.spec.js
│ ├── filters
│ │ └── filter3.js
│ │ └── filter3.spec.js
│ └── services
│ └── service3.js
│ └── service3.spec.js
├── partials
├── lib
└── e2e-tests
- În cazul în care un nume de director conține mai multe cuvinte, folosește sintaxa-tip-lisp:
app
├── app.js
└── my-complex-module
├── controllers
├── directives
├── filters
└── services
- Pune toate fișierele asociate cu o directivă (i.e. șabloane, fișiere CSS/SASS, JavaScript) într-un singur director. Dacă alegi să folosești acest stil, fii consistent și folosește-l peste tot în proiectul tău.
app
└── directives
├── directive1
│ ├── directive1.html
│ ├── directive1.js
│ ├── directive1.spec.js
│ └── directive1.sass
└── directive2
├── directive2.html
├── directive2.js
├── directive2.spec.js
└── directive2.sass
Această metodă poate fi combinată cu ambele structuri de directoare de mai sus.
- Testele de unitate pentru un anumit component (
*.spec.js
) ar trebui să fie localizate în directorul în care se află componentul. În acest fel poți face schimbări la un anumit component deoarece testarea este ușoară. Testele funcționează de asemenea ca documentare și studii de caz.
services
├── cache
│ ├── cache1.js
│ └── cache1.spec.js
└── models
├── model1.js
└── model1.spec.js
- Fișierul
app.js
ar trebui să conțină definiții de rute, configurație și/sau autoinițializare manuală (dacă este necesar). - Fiecare fișier de JavaScript ar trebui să conțină un singur component. Fișierul ar trebui să fie numit cu numele componentului.
- Folosește șablonul structurii de proiect precum Yeoman, ng-boilerplate.
Convenții despre numirea componentelor pot fi găsite în secțiunea fiecărui component.
PL;NC Pune script-urile la final.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>MyApp</title>
</head>
<body>
<div ng-app="myApp">
<div ng-view></div>
</div>
<script src="angular.js"></script>
<script src="app.js"></script>
</body>
</html>
Păstrează lucrurile simplu și pune directive specifice AngularJS după atributele standard. Aceasta va face parcurgerea codului mai ușoară și va fi mai ușor de menținut deoarece atributele sunt grupate și poziționate consistent.
<form class="frm" ng-submit="login.authenticate()">
<div>
<input class="ipt" type="text" placeholder="name" require ng-model="user.name">
</div>
</form>
Alte atribute HTML ar trebui să urmeze recomandarea Code Guide
Următorul tabel arată convențiile de numere pentru fiecare element:
Element | Stil de numire | Exemplu | Folosire |
---|---|---|---|
Module | scrieCamilăMic | angularApp | |
Controlere | Funcționalitate + 'Ctrl' | AdminCtrl | |
Directive | scrieCamilăMic | userInfo | |
Filtre | scrieCamilăMic | userFilter | |
Servicii | scrieCamilăMare | User | constructor |
Fabrici | scrieCamilăMic | dataFactory | others |
- Folosește:
$timeout
în loc desetTimeout
$interval
în loc desetInterval
$window
în loc dewindow
$document
în loc dedocument
$http
în loc de$.ajax
$location
în loc dewindow.location
sau$window.location
$cookies
în loc dedocument.cookie
Asta îți va face testarea mai ușoară iar în unele cazuri va preveni comportamentul neașteptat (de exemplu, dacă ai uitat $scope.$apply
în setTimeout
).
-
Automează-ți fluxul de lucru folosind unelte ca:
-
Folosește promisiuni (
$q
) în loc de reveniri. Îți va face codul să arate mai elegant și mai curat, și te va scăpa de iadul revenirilor. -
Folosește
$resource
în loc de$http
atunci când este posibil. Nivelul mai înalt de abstracție te va scăpa de redundanță. -
Folosește un pre-minificator AngularJS (ng-annotate) pentru a preveni problemele de după minificare.
-
Nu folosi globale. Rezolvă toate dependențele folosind Injectarea Dependențelor, aceasta va preveni bug-urile și cârpirea codului la testare.
-
Evită globalele folosind Grunt/Gulp pentru a înveli codul în Expresii Funcții Invocate Imediat (EFII/IIFE). Poți folosi plugin-uri ca grunt-wrap sau gulp-wrap pentru acest scop. Exemplu (folosind Gulp)
gulp.src("./src/*.js") .pipe(wrap('(function(){\n"use strict";\n<%= contents %>\n})();')) .pipe(gulp.dest("./dist"));
-
Nu-ți polua
$scope
-ul. Adaugă doar funcții și variable care sunt folosite în șabloane. -
Preferă folosirea controlerelor în loc de
ngInit
. Există doar câteva folosiri adecvate pentrungInit
, de exemplu pentru redenumirea proprietăților speciale înngRepeat
, și pentru injectarea de data prin scriptare din partea server-ului. Pe lângă aceste câteva cazuri, ar trebui să folosești controlere mai degrabă decâtngInit
pentru a inițializa valori într-un scop. Expresia predată luingInit
ar trebui să treacă prin lexicalizare, parsare și evaluare de către interpretatorul Angular implementat în serviciul$parse
. Aceasta conduce la:- Impact asupra performanței, deoarece interpretatorul este implementat în JavaScript;
- Arhivarea expresiilor parsate în interiorul serviciului
$parse
nu are mult sens în cele mai multe cazuri, deoarece expresiilengInit
sunt evaluate doar o dată; - Este dispus erorii, deoarece scrii șiruri de caractere în interiorul șabloanelor nu există evidențierea sintaxei și suport adițional din partea editorului.
- Nu sunt aruncate erori la rulare
-
Nu folosi
$
ca prefix pentru numele variabilelor, proprietăților, sau metodelor. Acest prefix este rezervat pentru folosirea de către AngularJS. -
Nu folosi
JQUERY
în interiorul aplicației. Dacă trebuie, folosește în locJQLite
cuangular.element
. -
Atunci când rezolvi dependențe prin mecanismul de Injectarea Dependențelor al AngularJS sortează dependențele prin tipul lor - dependențele contruite-în AngularJS ar trebui să fie primele, urmate de cele ale tale:
module.factory('Service', function ($rootScope, $timeout, MyCustomDependency1, MyCustomDependency2) {
return {
//Something
};
});
-
Modulele ar trebui să fie numite cu scriereCămilăMic. Pentru a indica că modulul
b
este un submodul al modululuia
le poți încorpora folosind înspațierea în nume ca:a.b
.Există două feluri comune de a structura modulele:
- Prin funcționalitate
- Prin tipul componentului
Momentan, nu este o diferență majoră, dar primul mod arată mai curat. De asemenea, dacă încărcarea-leneșă a modulelor este implementată (momentan nu este în harta de dezvoltare a AngularJS), va crește performanța aplicației.
-
Nu manipula DOM-ul în controlere, aceasta va face controlerele mai greu de testat și va viola Principiul de Separare a Grijilor. Folosește directive în schimb.
-
Numirea controlerului este făcută folosind funcționalitatea controlerului (de exemplu coș de cumpărături, pagină principală, panou admin) și subșirul
Ctrl
la final. -
Controlere sunt constructori în JavaScript simplu, astfel că vor fi numite folosind ScriereaCămilăMare (
HomePageCtrl
,ShoppingCartCtrl
,AdminPanelCtrl
, etc.). -
Controlerele nu ar trebui să fie definite ca globale (chiar dacă AngularJS permite asta, este o practică proastă să poluezi înspațierea de nume global).
-
Folosește următoarea sintaxă pentru definirea controlerelor:
function MyCtrl(dependency1, dependency2, ..., dependencyN) { // ... } module.controller('MyCtrl', MyCtrl);
Pentru a preveni problemele cu minificarea poți genera automat sintaxa de definire a matricii din cea standard foloding unelte ca ng-annotate (și grunt grunt-ng-annotate).
O altă alternativă va fi de a folosi
$inject
ca:angular .module('app') .controller('HomepageCtrl', HomepageCtrl); HomepageCtrl.$inject = ['$log', '$http', 'ngRoute']; function HomepageCtrl($log, $http, ngRoute) { // ... }
-
Evită de a folosi serviciul
$scope
pentru a defini funcții și proprietăți ca părți ale controlerelor. Folosește$scope
doar dacă este necesar: 0. Pentru publicarea și subscrierea la evenimente:$scope.$emit
,$scope.$broadcast
, și$scope.$on
. 0. Pentru valori și colecții watch:$scope.$watch
,$scope.$watchCollection
-
Preferă folosirea sintaxei
controller as
și captureazăthis
folosind o variabilă:<div ng-controller="MainCtrl as main"> {{ main.things }} </div>
app.controller('MainCtrl', MainCtrl); MainCtrl.$inject = ['$http']; function MainCtrl ($http) { var vm = this; // o conexiune vizuală mai clară despre cum este definită în vedere vm.title = 'Some title'; vm.description = 'Some description'; $http.get('/api/main/things').then(function (response) { vm.things = response.data.things; // Adăugarea 'things' ca proprietate a controlerului }); }
Evită folosirea cuvântului
this
în mod repetat într-un controler:app.controller('MainCtrl', MainCtrl); MainCtrl.$inject = ['$http']; // evită function MainCtrl ($http) { this.title = 'Some title'; this.description = 'Some description'; $http.get('/api/main/things').then(function (response) { // Atenție! 'this' este în alt context aici // Proprietatea nu va fi adăugată ca parte a contextului controlerului this.things = response.data.things; }); }
Folosirea unui nume consistent și scurt este preferat, de exemplu
vm
.Beneficiile principale de a folosi această sintaxă:
- Creează un component 'izolat' - proprietățile legate nu sunt parte a lanțului prototipal
$scope
. Aceasta este o practică deoarece ereditatea prototipală a$scope
are câteva dezavantaje majore (acesta este probabil motivul pentru a care a fost scos din Angular 2):- Este greu de ținut cont de unde vine data.
- Schimbările valorile scopului pot afecta locuri pe caren nu ai intenționat să le afectezi.
- Mai greu de refactorizat.
- 'regula punct'.
- Renunță la folosirea
$scope
acolo unde nu este nevoie de operații speciale (așa cum este menționat mai sus). Aceasta este o bună pregătire pentru AngularJS V2. - Sintaxa este mai apropiată de constructorul JavaScript 'vanilie'.
Săpând mai adânc în
controller as
: săpând-în-controlerele-angular-ca-sintaxă - Creează un component 'izolat' - proprietățile legate nu sunt parte a lanțului prototipal
-
În folosirea sintaxei de definirea matricei, folosește numele originale ale dependenței controlerelor. Aceasta te va ajuta să produci un cod mai citibil:
function MyCtrl(l, h) { // ... } module.controller('MyCtrl', ['$log', '$http', MyCtrl]);
care este mai puțin citibil decât:
function MyCtrl($log, $http) { // ... } module.controller('MyCtrl', ['$log', '$http', MyCtrl]);
Aceasta se aplică în mod special la un fișier care are atât de mult cod încât trebuie să faci scroll prin el. Aceasta te va face poate să uiți ce variabilă este legată de care dependență.
-
Fă controlerele cât mai subțiri. Abstractiează funcțiile folosite în mod comun într-un serviciu.
-
Evită scrierea logicii de afacere în interiroul controlerelor. Delegă logica de afacere într-un
model
, folosind un serviciu. De exemplu:// Acesta este un comportament comun (exemplu negativ) de a folosi logica de afacere în interiorul unui controler. angular.module('Store', []) .controller('OrderCtrl', function () { var vm = this; vm.items = []; vm.addToOrder = function (item) { vm.items.push(item);//--> Logică de afacere în interiorul controlerului }; vm.removeFromOrder = function (item) { vm.items.splice(vm.items.indexOf(item), 1);//--> Logică de afacere în interiorul controlerului }; vm.totalPrice = function () { return vm.items.reduce(function (memo, item) { return memo + (item.qty * item.price);//--> Logică de afacere în interiorul controlerului }, 0); }; });
Atunci când delegi logica de afacere într-un serviciu de
model
, controlerul va arăta atfel (vezi 'folosește servicii ca Model' pentru implementarea serviciului-model):// order este folosit ca 'model' angular.module('Store', []) .controller('OrderCtrl', function (order) { var vm = this; vm.items = order.items; vm.addToOrder = function (item) { order.addToOrder(item); }; vm.removeFromOrder = function (item) { order.removeFromOrder(item); }; vm.totalPrice = function () { return order.total(); }; });
De ce logica de afacere / starea aplicației din interiorul controlerului este rea?
- Controlerele sunt instanțiate pentru fiecare vedere și moare atunci când vederea este descărcată.
- Controlerele nu sunt refolosibile - ele sunt cuplat cu vederea.
- Controlerele nu sunt menite să fie injectate.
-
Comunică în cadrul diferitelor controlere folosind invocarea metodei (posibilă atunci când un copil vrea să comunice cu părintele său) sau metodele
$emit
,$broadcast
, și$on
. Mesajele emise sau comunicate ar trebui să fie păstrate la un minim. -
Fă o listă a tuturor mesajelor care sunt predate prin
$emit
,$broadcast
și administreaz-o cu atenție datorită coliziunilor de nume și a posibilelor bug-uri.Exemple:
// app.js /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Evenimente specifice: - 'authorization-message' - descrierea mesajului - { user, role, action } - formatul data - user - un șir de caractere, care conține numele de utilizator - role - un ID al unui rol avut de utilizator - action - acțiunea specifică pe care încearcă să o facă utilizatorul * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
Atunci când trebuie să formatezi data, encapsulează logica de formatare într-un filtru și declar-o ca o dependență:
function myFormat() { return function () { // ... }; } module.filter('myFormat', myFormat); function MyCtrl($scope, myFormatFilter) { // ... } module.controller('MyCtrl', MyCtrl);
-
În cazul controlerelor grupate folosește „scope grupat” (sintaxa
controllerAs
):app.js
module.config(function ($routeProvider) { $routeProvider .when('/route', { templateUrl: 'partials/template.html', controller: 'HomeCtrl', controllerAs: 'home' }); });
HomeCtrl
function HomeCtrl() { var vm = this; vm.bindingValue = 42; }
template.html
<div ng-bind="home.bindingValue"></div>
- Numește-ți directive cu scriereCămilăMică.
- Folosește
scope
în locul$scope
în funcția de legare. În funcțiile de compilare, pre/post legare ai definit deja argumente care vor fi predate atunci când funcția este invocată, nu vei fi capabil să le schimbi atunci când folosești Injectarea Dependenței. Acest stil este de asemenea folosit în codul sursă AngularJS. - Folosește prefixe specifice pentru directive pentru a preveni coliziunile cu biblioteci ale unor părți terțiare.
- Nu folosi prefixe
ng
sauui
deoarece sunt rezervate pentru folosirea AngularJS sau AngularJS UI. - Manipularea DOM trebuie făcută doar prin directive.
- Creează un scop izolat atunci când dezvolți componente reutilizabile.
- Folosește directive ca atribute sau elemente în loc de comentarii sau clase, îți vor face codul mai citibil.
- Folosește
scope.$on('$destroy', fn)
pentru curățire. Aceasta este în special folosibil atunci când învelești directive sau plugin-uri din părți terțe. - Nu uita să folosești
$sce
atunci când ar trebui să lucrezi cu conținut ce nu poate fi crezut.
- Numește-ți filtrele folosind scriereCămilăMic.
- Fă-ți filtrele cât mai ușoare posibil. Ele sunt chemate des în timpul ciclului
$digest
astfel încât crearea unui filtru încet îți va încetini aplicația. - Fă un singur lucru în filtre, păstrează-le coerente. Manipulări mai complexe pot fi obținute prin înțevuirea filtrele existente.
Această secțiune include informație despre serviciul component în AngularJS. Nu este dependent de felul definiției (i.e. ca furnizor, .factory
, .service
), cu excepția dacă este menționată explicit.
-
Folosirea scriereCămilăMic pentru a-ți numi serviciile.
-
ScriereaCămilăMare (ScriereaPascal) pentru numirea serviciilor, folosite ca funcții constructor, i.e.:
function MainCtrl(User) { var vm = this; vm.user = new User('foo', 42); } module.controller('MainCtrl', MainCtrl); function User(name, age) { this.name = name; this.age = age; } module.factory('User', function () { return User; });
-
scriereCămilăMic pentru toate celelalte servicii.
-
Encapsulează-ți toată logica de afaceri în servicii. Preferă să o folosești ca
model
. De exemplu:// order este 'model'-ul angular.module('Store') .factory('order', function () { var add = function (item) { this.items.push (item); }; var remove = function (item) { if (this.items.indexOf(item) > -1) { this.items.splice(this.items.indexOf(item), 1); } }; var total = function () { return this.items.reduce(function (memo, item) { return memo + (item.qty * item.price); }, 0); }; return { items: [], addToOrder: add, removeFromOrder: remove, totalPrice: total }; });
-
Vezi 'Evitarea scrierii logicii de afaceri în controlere' pentru un exemplu a unui controler care consumă acest serviciu.
-
Serviciile reprezentând domeniul preferă un
service
în loc de unfactory
. În acest fel putem valorifica de ereditarea "klassical"ă mai ușor:function Human() { //body } Human.prototype.talk = function () { return "I'm talking"; }; function Developer() { //body } Developer.prototype = Object.create(Human.prototype); Developer.prototype.code = function () { return "I'm coding"; }; myModule.service('human', Human); myModule.service('developer', Developer);
-
Pentru arhivarea la nivel de sesiune poți folosi
$cacheFactory
. Aceasta ar trebui să fie folosită pentru a arhiva rezultate din cereri și computații grele. -
Dacă un anumit serviciu necesită configurare, definește serviciul ca furnizor și configurează-l în revenirea
config
ca:angular.module('demo', []) .config(function ($provide) { $provide.provider('sample', function () { var foo = 42; return { setFoo: function (f) { foo = f; }, $get: function () { return { foo: foo }; } }; }); }); var demo = angular.module('demo'); demo.config(function (sampleProvider) { sampleProvider.setFoo(41); });
- Folosește
ng-bind
saung-cloak
în loc de simple{{ }}
pentru a preveni fulgerarea conținutului. - Evită scrierea de expresii complexe în șabloane.
- Atunci când trebuie să setezi
src
-ul unei imagini dinamic foloseșteng-src
în loc desrc
cu șablon{{ }}
. - Atunci când trebuie să setezi
href
-ul unei etichete ancoră dinamic foloseșteng-href
în loc dehref
cu șablon{{ }}
. - În loc de a folosi variabile de scop ca șir de caractere și a folosi atributul
style
cu{{ }}
, folosește directivang-style
cu parametri ca-obiecte și variabile de scop ca valori:
<div ng-controller="MainCtrl as main">
<div ng-style="main.divStyle">my beautifully styled div which will work in IE</div>;
</div>
angular
.module('app')
.controller('MainCtrl', MainCtrl);
MainCtrl.$inject = [];
function MainCtrl() {
var vm = this;
vm.divStyle = {
width: 200,
position: 'relative'
};
}
- Folosește
resolve
pentru a rezolva dependențele înainte ca vederea să fie aratată. - Nu plasa chemări explicite REST înăutru revenirii
resolve
. Izolează toate cererile înăutru serviciilor adecvate. În acest fel poți activa arhivarea și urmări principiul separării grijei.
Testarea Capăt-La-Capăt sunt pasul următor după testele de unitate care-ți vor permite să urmărești bug-urile și erorile din sistem. Sunt foarte utile în a asigura o verificare de sanitate în cele mai comune scenarii din folosirea aplicației tale. În acest fel poți automatiza procesul și rula înainte de fiecare dată de ați instala aplicația.
Ideal, teste Capăt-La-Capăt Angular sunt scrise în Jasmine. Aceste teste sunt rulate folosind Protractor E2E care folosește evenimente native și are funcții speciale pentru aplicații Angular.
Structura fișierelor:
.
├── app
│ ├── app.js
│ ├── home
│ │ ├── home.html
│ │ ├── controllers
│ │ │ ├── FirstCtrl.js
│ │ │ ├── FirstCtrl.spec.js
│ │ ├── directives
│ │ │ └── directive1.js
│ │ │ └── directive1.spec.js
│ │ ├── filters
│ │ │ ├── filter1.js
│ │ │ └── filter1.spec.js
│ │ └── services
│ │ ├── service1.js
│ │ └── service1.spec.js
│ └── about
│ ├── about.html
│ ├── controllers
│ │ └── ThirdCtrl.js
│ │ └── ThirdCtrl.spec.js
│ └── directives
│ ├── directive2.js
│ └── directive2.spec.js
├── partials
├── lib
└── e2e-tests
├── protractor.conf.js
└── specs
├── home.js
└── about.js
- Pentru versiuni mai noi ale framework-ului (>=1.4.0) folosește uneltele de i18n construite-în, atunci când folosești versiuni mai vechi (<1.4.0) folosește
angular-translate
.
-
Optimizează ciclul de digerare
- Vezi doar cele mai vitale variabile. Atunci când trebuie să invoice ciclul
$digest
explicit (ar trebui să se întâmple doar în cazuri excepționale), invoc-o doar atunci când este necesar (de exemplu: atunci când folosești comunicare în timp real, nu cauza un ciclu$digest
în fiecare mesaj primit). - Pentru conținutul care este inițializat doar o dată iar apoi niciodată schimbat, folosește veghetori o singură dată ca
bindonce
pentru versiuni mai vechi ale AngularJS sau legături o dată în AngularJS >=1.3.0.or<div> {{ ::main.things }} </div>
<div ng-bind="::main.things"></div>
După asta, niciun veghetor nu va fi creat pentru
main.things
și nicio schimbare amain.things
nu va aduce la zi vederea.- Fă computațiile în
$watch
cât de simple posibile. A face computații greoaie și încete într-un singur$watch
va înceta întreaga aplicației (ciclul$digest
este făcut într-un singur fir datorită naturii de fir-singur al JavaScript). - Atunci când veghezi colecții, nu le veghea adânc atunci când nu este necesar. Mai bine folosești
$watchCollection
care produce o verificare superficială pentru egalitatea expresiei vegheate cu valoarea anterioară a expresiei evaluate. - Setează al treilea parametru în funcția
$timeout
ca fals pentru a sări peste ciclul$digest
atunci când nicio variabilă nu e influențată de invocarea funcției de revenire$timeout
. - Atunci când te ocupi de colecții mari, care se schimbă rar, folosește structuri de data imutabile.
- Vezi doar cele mai vitale variabile. Atunci când trebuie să invoice ciclul
-
Consideră descreșterea numărului de cereri de la rețea prin gruparea/arhivarea fișierelor șablon
html
în fișierul JavaScript principal, folosind grunt-html2js / gulp-html2js. Vezi aici și aici pentru detalii. Aceasta este util în mod special atunci când proiectul are un număr mare de șabloanehtml
mici care pot fi parte din fișierul JavaScript principal (minificat sau gzip-at).
Deoarece scopul acestui ghid de stil este de a fi condus de comunitate, contribuțiile sunt foarte apreciate. De exemplu, poți contribui prin extinderea secțiune de Testare sau prin traducerea ghidului de stil în limba maternă.
mgechev | morizotter | chatii2412 | pascalockert | yanivefraim | ericguirbal |
agnislav | ray7551 | mainyaa | LeonardCModoran | elfinxx | tiagobarreto |
Xuefeng-Zhu | SullyP | giacomocusinato | rubystream | lukaszklis | Spuffynism |
susieyy | cironunes | cavarzan | guiltry | MSafter | mingchen |
jmblog | luixaviles | andreasonny83 | kuzzmi | jabhishek | adambabik |
astalker | clbn | atodorov | apetro | valgreens | bitdeli-chef |
meetbryce | unseen1980 | cminhho | dwmkerr | kuzmeig1 | dominickolbe |
gsamokovarov | grvcoelho | yassirh | bargaorobalo | hermankan | jesselpalmer |
capaj | johnnyghost | jordanyee | whoan | nacyot | mariolamacchia |
mischkl | michaelmov | kirstein | mo-gr | mortonfox | cryptojuice |
nktssh | olafahn | olov | vorktanamobay | QuietHeartThinkingFar | raphaelfruneaux |
sahat | ganchiku | kaneshin | imaimiami | dooart | thomastuts |
UrielMiranda | vkarampinis | grapswiz | coderhaoxin | giantray | ntaoo |
seyyah | dchest |