├── LICENSE
├── README-de-de.md
├── README-es-es.md
├── README-fr-fr.md
├── README-id-id.md
├── README-it-it.md
├── README-ja-jp.md
├── README-ko-kr.md
├── README-pl-pl.md
├── README-pt-br.md
├── README-ro-ro.md
├── README-ru-ru.md
├── README-sr-lat.md
├── README-sr.md
├── README-tr-tr.md
├── README-zh-cn.md
└── README.md
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Minko Gechev
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README-de-de.md:
--------------------------------------------------------------------------------
1 | # Einleitung
2 |
3 | Das Ziel dieses Style Guides ist, eine Sammlung von Best Practices und Gestaltungsrichtlinien für AngularJS-Anwendungen aufzuzeigen.
4 | Sie wurden aus den folgenden Quellen zusammengestellt:
5 |
6 | 0. AngularJS-Quelltext
7 | 0. Quelltexte oder Artikel, die ich gelesen habe
8 | 0. Meine eigene Erfahrung
9 |
10 | **Hinweis 1:** Hierbei handelt es sich noch um einen Entwurf des Style Guides, dessen vorrangiges Ziel es ist, gemeinschaftlich von der Community entwickelt zu werden. Die gesamte Community wird es daher begrüßen, wenn Lücken gefüllt werden.
11 | **Hinweis 2:** Bevor du den Richtlinien in einer der Übersetzungen des englischsprachigen Dokuments folgst, vergewissere dich, dass diese aktuell sind. Die jüngste Version des AngularJS Style Guide ist im Dokument README.md.
12 |
13 | Du wirst in diesem Style Guide keine allgemeinen Richtlinien für die JavaScript-Entwicklung finden. Solche finden sich unter:
14 |
15 | 0. [Googles JavaScript-Style-Guide](https://google.github.io/styleguide/javascriptguide.xml)
16 | 0. [Mozillas JavaScript-Style-Guide](https://developer.mozilla.org/en-US/docs/Developer_Guide/Coding_Style)
17 | 0. [Douglas Crockfords JavaScript-Style-Guide](http://javascript.crockford.com/code.html)
18 | 0. [Airbnb JavaScript-Style-Guide](https://github.com/airbnb/javascript)
19 |
20 | Für die AngularJS-Entwicklung ist [Googles JavaScript-Style-Guide](https://google.github.io/styleguide/javascriptguide.xml) empfehlenswert.
21 |
22 | Im GitHub-Wiki von AngularJS gibt es einen ähnlichen Abschnitt von [ProLoser](https://github.com/ProLoser), den du dir [hier](https://github.com/angular/angular.js/wiki) ansehen kannst.
23 |
24 | # Inhaltsverzeichnis
25 | * [Allgemein](#allgemein)
26 | * [Verzeichnisstruktur](#verzeichnisstruktur)
27 | * [Markup](#markup)
28 | * [Optimieren des Digest-Zyklus](#optimieren-des-digest-zyklus)
29 | * [Sonstiges](#sonstiges)
30 | * [Namensgebung](#namensgebung)
31 | * [Module](#module)
32 | * [Controller](#controller)
33 | * [Direktiven](#direktiven)
34 | * [Filter](#filter)
35 | * [Services](#services)
36 | * [Templates](#templates)
37 | * [Routing](#routing)
38 | * [Testen](#testen)
39 | * [Mitmachen](#mitmachen)
40 | * [Mitwirkende](#mitwirkende)
41 |
42 | # Allgemein
43 |
44 | ## Verzeichnisstruktur
45 |
46 | Da eine große AngularJS-Anwendung viele Komponenten hat, sollten diese mit Hilfe einer Verzeichnishierarchie strukturiert werden.
47 | Es gibt zwei Basis-Herangehensweisen:
48 |
49 | * Auf einer oberen Ebene eine Aufteilung nach Art der Komponenten und auf einer tieferen Ebene eine Aufteilung nach Funktionalität.
50 |
51 | Die Verzeichnisstruktur wird in diesem Fall folgendermaßen aussehen:
52 |
53 | ```
54 | .
55 | ├── app
56 | │ ├── app.js
57 | │ ├── controllers
58 | │ │ ├── page1
59 | │ │ │ ├── FirstCtrl.js
60 | │ │ │ └── SecondCtrl.js
61 | │ │ └── page2
62 | │ │ └── ThirdCtrl.js
63 | │ ├── directives
64 | │ │ ├── page1
65 | │ │ │ └── directive1.js
66 | │ │ └── page2
67 | │ │ ├── directive2.js
68 | │ │ └── directive3.js
69 | │ ├── filters
70 | │ │ ├── page1
71 | │ │ └── page2
72 | │ └── services
73 | │ ├── CommonService.js
74 | │ ├── cache
75 | │ │ ├── Cache1.js
76 | │ │ └── Cache2.js
77 | │ └── models
78 | │ ├── Model1.js
79 | │ └── Model2.js
80 | ├── partials
81 | ├── lib
82 | └── test
83 | ```
84 |
85 | * Auf einer oberen Ebene eine Aufteilung nach Funktionalität und auf einer tieferen Ebene eine Aufteilung nach Art der Komponenten.
86 |
87 | Hier ist das entsprechende Layout:
88 |
89 | ```
90 | .
91 | ├── app
92 | │ ├── app.js
93 | │ ├── common
94 | │ │ ├── controllers
95 | │ │ ├── directives
96 | │ │ ├── filters
97 | │ │ └── services
98 | │ ├── page1
99 | │ │ ├── controllers
100 | │ │ │ ├── FirstCtrl.js
101 | │ │ │ └── SecondCtrl.js
102 | │ │ ├── directives
103 | │ │ │ └── directive1.js
104 | │ │ ├── filters
105 | │ │ │ ├── filter1.js
106 | │ │ │ └── filter2.js
107 | │ │ └── services
108 | │ │ ├── service1.js
109 | │ │ └── service2.js
110 | │ └── page2
111 | │ ├── controllers
112 | │ │ └── ThirdCtrl.js
113 | │ ├── directives
114 | │ │ ├── directive2.js
115 | │ │ └── directive3.js
116 | │ ├── filters
117 | │ │ └── filter3.js
118 | │ └── services
119 | │ └── service3.js
120 | ├── partials
121 | ├── lib
122 | └── test
123 | ```
124 |
125 | * Wenn eine Direktive erstellt wird, kann es sinnvoll sein, alle der Direktive zugehörigen Dateien (d. h. Templates, CSS/SASS-Dateien, JavaScript) in das selbe Verzeichnis zu legen. Wenn du dich für diesen Stil entscheidest, setze ihn konsequent im gesamten Projekt um.
126 |
127 | ```
128 | app
129 | └── directives
130 | ├── directive1
131 | │ ├── directive1.html
132 | │ ├── directive1.js
133 | │ └── directive1.sass
134 | └── directive2
135 | ├── directive2.html
136 | ├── directive2.js
137 | └── directive2.sass
138 | ```
139 |
140 | Dieser Ansatz kann mit beiden der oben genannten Verzeichnisstrukturen kombiniert werden.
141 | * Eine weitere kleine Variation der beiden Verzeichnisstrukturen wird in [ng-boilerplate](http://joshdmiller.github.io/ng-boilerplate/#/home) eingesetzt. In dieser liegen die Unit Tests zu einer Komponente direkt im Verzeichnis der jeweiligen Komponente. Werden Änderungen an einer Komponente vorgenommen, ist es auf diese Weise einfacher, ihre Tests zu finden. Gleichzeitig dienen die Tests als Dokumentation und zeigen Anwendungsfälle auf.
142 |
143 | ```
144 | services
145 | ├── cache
146 | │ ├── cache1.js
147 | │ └── cache1.spec.js
148 | └── models
149 | ├── model1.js
150 | └── model1.spec.js
151 | ```
152 |
153 | * Die Datei `app.js` enthält die Routendefinitionen, die Konfiguration und/oder das manuelle Bootstrapping (falls benötigt).
154 | * Jede JavaScript-Datei sollte nur eine einzige Komponente enthalten. Die Datei sollte nach dem Namen der Komponente benannt sein.
155 | * Verwende Angular-Projektstrukturvorlagen wie [Yeoman](http://yeoman.io) oder [ng-boilerplate](http://joshdmiller.github.io/ng-boilerplate/#/home).
156 |
157 | Ich bevorzuge die erste Struktur, weil bei ihr die üblichen Komponenten einfacher gefunden werden können.
158 |
159 | Konventionen über die Benennung der Komponenten stehen in jedem Abschnitt über die jeweilige Komponente.
160 |
161 | ## Markup
162 |
163 | Auch die HTML-Markup ist wichtig und sollte in einem Team so geschrieben werden, als sei sie von derselben Person.
164 |
165 | [TLDR;](http://developer.yahoo.com/blogs/ydn/high-performance-sites-rule-6-move-scripts-bottom-7200.html) Scripts sollten am Ende einer Seite eingefügt werden.
166 |
167 | ```
168 |
169 |
170 |
171 |
172 | Meine App
173 |
174 |
175 |
178 |
179 |
180 |
181 |
182 | ```
183 |
184 | Um den Code nicht unnötig zu verkomplizieren, füge AngularJS-spezifische Direktiven hinter Standard-Attributen ein. Dadurch ist es einfacher, sich den Code anzusehen und durch das Framework erweitertes HTML zu erkennen (was die Wartbarkeit verbessert).
185 |
186 | ```
187 |
192 | ```
193 |
194 | Andere HTML-Attribute sollten den [Empfehlungen](http://mdo.github.io/code-guide/#html-attribute-order) des Code Guides folgen.
195 |
196 | ## Optimieren des Digest-Zyklus
197 |
198 | * Watche nur auf die vitalsten Variablen (Beispiel: Wenn du eine Echtzeitkommunikation einsetzt, sollte nicht bei jeder eingehenden Nachricht ein `$digest`-Loop ausgelöst werden).
199 | * Für Inhalte, die nur einmal initialisiert und anschließend nicht mehr geändert werden, sollten Einmal-Watcher wie [`bindonce`](https://github.com/Pasvaz/bindonce) verwendet werden.
200 | * Vereinfache Berechnungen in `$watch` so weit wie möglich. Komplexe und langsame Berechnungen in einem einzigen `$watch` verlangsamen die gesamte Applikation (der `$digest`-Loop wird in einem einzelnen Thread ausgeführt, weil JavaScript single-threaded ist).
201 | * Falls in der Callback-Funktion von `$timeout` keine gewatchten Variablen geändert werden, setze den dritten Parameter der `$timeout`-Funktion auf `false`, um nicht automatisch einen `$digest`-Zyklus durch den Aufruf des Callbacks auszulösen.
202 |
203 | ##Namensgebung
204 | Die Namensgebung für alle Elemente sind in folgender Tabelle wieder zu finden:
205 |
206 | Element | Style | Beispiel | Verwendung bei
207 | ----|------|----|--------
208 | Module | lowerCamelCase | angularApp |
209 | Controller | funktionalität + 'Ctrl' | adminCtrl |
210 | Direktiven | lowerCamelCase | userInfo |
211 | Filter | lowerCamelCase | userFilter |
212 | Services | UpperCamelCase | User | Konstruktor
213 | Services | lowerCamelCase | dataFactory | sonstige
214 |
215 | ## Sonstiges
216 |
217 | * Verwende:
218 | * `$timeout` statt `setTimeout`
219 | * `$interval` statt `setInterval`
220 | * `$window` statt `window`
221 | * `$document` statt `document`
222 | * `$http` statt `$.ajax`
223 |
224 | Dadurch werden deine Tests einfacher und in manchen Fällen wird einem unerwarteten Verhalten vorgebeugt (zum Beispiel wenn du ein `$scope.$apply()` in `setTimeout` vergessen hast).
225 |
226 | * Automatisiere deinen Workflow mit Tools wie:
227 | * [Yeoman](http://yeoman.io)
228 | * [Grunt](http://gruntjs.com)
229 | * [Bower](http://bower.io)
230 |
231 | * Verwende Promises (`$q`) statt Callbacks. Dadurch sieht dein Code eleganter und sauberer aus und du wirst nicht in der Callback-Hölle landen.
232 | * Verwende, wenn möglich, `$resource` statt `$http`. Das höhere Abstraktionslevel schützt dich vor Redundanz.
233 | * Verwende einen Angular Pre-Minifier (wie [ngmin](https://github.com/btford/ngmin) oder [ng-annotate](https://github.com/olov/ng-annotate)), um Probleme nach einer Minification zu vermeiden.
234 | * Verwende keine Globalen. Löse alle Abhängigkeiten durch Dependency Injection auf.
235 | * Mülle deinen `$scope` nicht zu. Füge ihm nur Funktionen und Variablen hinzu, die in den Templates verwendet werden.
236 | * Bevorzuge [Controller gegenüber `ngInit`](https://github.com/angular/angular.js/pull/4366/files). `ngInit` eignet sich nur, um Aliase für spezielle Eigenschaften von `ngRepeat` zu erstellen. Hiervon abgesehen solltest du immer Controller statt `ngInit` verwenden, um Werte in einem Scope zu initialisieren.
237 | * Verwende kein `$` als Präfix für die Namen von Variablen, Eigenschaften oder Methoden. Dieser Präfix ist für AngularJS reserviert.
238 |
239 | # Module
240 |
241 | * Module sollten in lowerCamelCase benannt werden. Um deutlich zu machen, dass das Modul `b` ein Untermodul von `a` ist, kannst du sie durch Namespaces verschachteln, z. B.: `a.b`.
242 |
243 | Es gibt zwei verbreitete Wege, nach denen Module strukturiert werden können:
244 |
245 | 0. Nach Funktionalität
246 | 0. Nach Typ der Komponente
247 |
248 | Derzeit gibt es keinen großen Unterschied, aber die erste Variante sieht sauberer aus. Außerdem wird - wenn lazy-loading für die Module implementiert ist (momentan nicht auf der AngularJS-Roadmap) - die Performance der App verbessert.
249 |
250 | # Controller
251 |
252 | * Du solltest das DOM nicht aus deinen Controllern heraus manipulieren, dadurch wird das Testen der Controller erschwert und du verstößt gegen das [Prinzip der Separation of Concerns](https://en.wikipedia.org/wiki/Separation_of_concerns). Verwende stattdessen Direktiven.
253 | * Controller sollen nach ihrer Funktion (zum Beispiel shopping cart, homepage, admin panel) und dem Suffix `Ctrl` benannt werden. Controller werden in UpperCamelCase benannt (`HomePageCtrl`, `ShoppingCartCtrl`, `AdminPanelCtrl` usw.).
254 | * Controller sollten nicht als Globale definiert werden (AngularJS erlaubt das zwar, es ist jedoch schlechte Praxis den globalen Namensraum zu verschmutzen).
255 | * Verwende für Controller-Definitionen die Array-Syntax:
256 |
257 | ```JavaScript
258 | module.controller('MyCtrl', ['dependency1', 'dependency2', ..., 'dependencyn', function(dependency1, dependency2, ..., dependencyn) {
259 | // body
260 | }]);
261 | ```
262 |
263 | Durch die Verwendung dieses Definitionstyps werden Probleme bei der Minification vermieden. Die Array-Definition kann aus der Standardnotation automatisch generiert werden, indem Werkzeuge wie [ng-annotate](https://github.com/olov/ng-annotate) (und der Grunt-Task [grunt-ng-annotate](https://github.com/mzgol/grunt-ng-annotate)) verwendet werden.
264 | * Verwende die Originalnamen der im Controller verwendeten Abhängigkeiten. Dies hilft dir dabei, lesbareren Code zu schreiben:
265 |
266 | ```JavaScript
267 | module.controller('MyCtrl', ['$scope', function(s) {
268 | // body
269 | }]);
270 | ```
271 |
272 | ist schlechter lesbar als:
273 |
274 | ```JavaScript
275 | module.controller('MyCtrl', ['$scope', function($scope) {
276 | // body
277 | }]);
278 | ```
279 |
280 | Das gilt insbesondere für Dateien, die so viel Code enthalten, dass gescrollt werden muss. Dadurch vergisst du möglicherweise, welche Variable zu welcher Abhängigkeit gehört.
281 |
282 | * Halte Controller so schlank wie möglich und lagere mehrfach verwendete Funktionen in Services aus.
283 | * Kommuniziere zwischen verschiedenen Controllern, indem du Method Invocation nutzt (das ist möglich, wenn ein Kindcontroller mit seinem Elterncontroller kommunizieren möchte) oder die `$emit`-, `$broadcast`- und `$on`-Methoden verwendest. Über `$emit` und `$broadcast` gesendete Nachrichten sollten auf ein Minimum reduziert werden.
284 | * Erstelle eine Liste aller Nachrichten, die über `$emit` und `$broadcast` verschickt werden. Pflege diese Liste, um Kollisionen und Bugs zu vermeiden.
285 | * Wenn du Daten formatieren musst, kapsle die Formatierungslogik in einem [Filter](#filter) und gebe diesen als Abhängigkeit an:
286 |
287 | ```JavaScript
288 | module.filter('myFormat', function() {
289 | return function() {
290 | // body
291 | };
292 | });
293 |
294 | module.controller('MyCtrl', ['$scope', 'myFormatFilter', function($scope, myFormatFilter) {
295 | // body
296 | }]);
297 | ```
298 |
299 | # Direktiven
300 |
301 | * Benenne deine Direktiven in lowerCamelCase.
302 | * Verwende `scope` statt `$scope` in deiner Link-Funktion. In den Compile- und Post-/Pre-Link-Funktionen hast du bereits Argumente angegeben, die verwendet werden sobald die Funktion aufgerufen wird. Diese kannst du nicht über eine Dependency Injection ändern. Dieser Stil wird auch im AngularJS-Sourcecode verwendet.
303 | * Verwende eigene Präfixe für deine Direktiven, um Namenskollisionen mit Bibliotheken von Drittanbietern zu vermeiden.
304 | * Die Präfixe `ng` und `ui` solltest du nicht verwenden, da diese für AngularJS und AngularUI reserviert sind.
305 | * DOM-Manipulationen dürfen ausschließlich über Direktiven vorgenommen werden.
306 | * Verwende einen Isolated Scope, wenn du wiederverwendbare Komponenten entwickelst.
307 | * Binde Direktiven über Attribute oder Elemente ein statt über Kommentare oder Klassen. Das macht deinen Code lesbarer.
308 | * Verwende zum Aufräumen `$scope.$on('$destroy', fn)`. Dies ist besonders nützlich wenn du Wrapper-Direktiven für Drittanbieter-Plug-ins entwickelst.
309 | * Vergiss nicht, `$sce` zu verwenden, wenn du mit Inhalten arbeitest, die nicht vertrauenswürdig sind.
310 |
311 | # Filter
312 |
313 | * Benenne deine Filter in lowerCamelCase.
314 | * Halte deine Filter so schlank wie möglich. Durch die `$digest`-Schleife werden sie häufig aufgerufen, so dass langsame Filter die gesamte Anwendung verlangsamen.
315 | * Mache nur eine einzige Sache in deinen Filtern, halte sie kohärent. Komplexere Manipulationen können erzielt werden, indem mehrere Filter gepiped werden.
316 |
317 | # Services
318 |
319 | Dieser Abschnitt enthält Informationen über AngularJS' Service-Komponente. Er bezieht sich nicht auf eine spezielle Definitionsweise (d. h. als Provider, Factory oder Service), falls nicht ausdrücklich genannt.
320 |
321 | * Benenne deine Services in camelCase.
322 | * UpperCamelCase (PascalCase), um Services zu benennen, die als Konstruktoren verwendet werden, d. h.:
323 |
324 | ```JavaScript
325 | module.controller('MainCtrl', function ($scope, User) {
326 | $scope.user = new User('foo', 42);
327 | });
328 |
329 | module.factory('User', function () {
330 | return function User(name, age) {
331 | this.name = name;
332 | this.age = age;
333 | };
334 | });
335 | ```
336 |
337 | * lowerCamelCase für alle anderen Services.
338 | * Kapsle die gesamte Anwendungslogik in Services.
339 | * Services, die eine bestimmte Domäne abbilden, sollten bevorzugt als `service` statt als `factory` geschrieben werden. Auf diese Weise können die Vorteile der klassischen Vererbung einfacher genutzt werden:
340 |
341 | ```JavaScript
342 | function Human() {
343 | // body
344 | }
345 | Human.prototype.talk = function() {
346 | return "I'm talking";
347 | };
348 |
349 | function Developer() {
350 | // body
351 | }
352 | Developer.prototype = Object.create(Human.prototype);
353 | Developer.prototype.code = function() {
354 | return "I'm coding";
355 | };
356 |
357 | myModule.service('Human', Human);
358 | myModule.service('Developer', Developer);
359 | ```
360 |
361 | * Für einen sitzungsbezogenen Cache kannst du `$cacheFactory` verwenden. Diesen solltest du nutzen, um die Ergebnisse von Anfragen oder aufwändigen Berechnungen zwischenzuspeichern.
362 | * Falls ein Service konfiguriert werden muss, definiere ihn als Provider und konfiguriere ihn im `config`-Callback, wie hier:
363 |
364 | ```JavaScript
365 | angular.module('demo', [])
366 | .config(function ($provide) {
367 | $provide.provider('sample', function () {
368 | var foo = 42;
369 | return {
370 | setFoo: function (f) {
371 | foo = f;
372 | },
373 | $get: function () {
374 | return {
375 | foo: foo
376 | };
377 | }
378 | };
379 | });
380 | });
381 |
382 | var demo = angular.module('demo');
383 |
384 | demo.config(function (sampleProvider) {
385 | sampleProvider.setFoo(41);
386 | });
387 | ```
388 |
389 | # Templates
390 |
391 | * Verwende `ng-bind` oder `ng-cloak` statt einfachen `{{ }}`, um flackernde Inhalte zu vermeiden.
392 | * Vermeide es, komplexe Ausdrücke in ein Template zu schreiben.
393 | * Wenn das `src`-Attribut eines Bilds dynamisch gesetzt werden soll, verwende `ng-src` statt `src` mit einem `{{ }}`-Template.
394 | * Wenn du das `href`-Attribut eines Ankers dynamisch setzen musst, verwende `ng-href` statt `href` mit einem `{{ }}`-Template.
395 | * Statt in Scopevariablen Strings anzugeben und diese mit `{{ }}` in ein `style`-Attribut zu schreiben, benutze die `ng-style`-Direktive, der als Parameter objektartige Strings und Scopevariablen übergeben werden können:
396 |
397 | ```JavaScript
398 | $scope.divStyle = {
399 | width: 200,
400 | position: 'relative'
401 | };
402 | ```
403 | ```HTML
404 | Mein wunderschön gestyltes div, das auch im IE funktioniert
;
405 | ```
406 |
407 | # Routing
408 |
409 | * Verwende `resolve`, um Abhängigkeiten aufzulösen bevor die View angezeigt wird.
410 |
411 | #Testen
412 |
413 | TBD
414 |
415 | Du kannst [diese Anleitung](https://github.com/daniellmb/angular-test-patterns) verwenden, solange dieser Abschnitt noch nicht fertig ist.
416 |
417 | # Mitmachen
418 |
419 | Da dieser Style Guide gemeinschaftlich durch die Community erstellt werden soll, sind Beiträge willkommen.
420 | Zum Beispiel kannst du etwas beitragen, indem du den Abschnitt über Tests erweiterst oder den Style Guide in deine Sprache übersetzt.
421 |
422 | #Mitwirkende
423 |
424 | [](https://github.com/mgechev) |[](https://github.com/pascalockert) |[](https://github.com/mainyaa) |[](https://github.com/rubystream) |[](https://github.com/lukaszklis) |
425 | :---: |:---: |:---: |:---: |:---: |
426 | [mgechev](https://github.com/mgechev) |[pascalockert](https://github.com/pascalockert) |[mainyaa](https://github.com/mainyaa) |[rubystream](https://github.com/rubystream) |[lukaszklis](https://github.com/lukaszklis) |
427 |
428 | [](https://github.com/cironunes) |[](https://github.com/cavarzan) |[](https://github.com/tornad) |[](https://github.com/jmblog) |[](https://github.com/bargaorobalo) |
429 | :---: |:---: |:---: |:---: |:---: |
430 | [cironunes](https://github.com/cironunes) |[cavarzan](https://github.com/cavarzan) |[tornad](https://github.com/tornad) |[jmblog](https://github.com/jmblog) |[bargaorobalo](https://github.com/bargaorobalo) |
431 |
432 | [](https://github.com/astalker) |[](https://github.com/valgreens) |[](https://github.com/bitdeli-chef) |[](https://github.com/dchest) |[](https://github.com/gsamokovarov) |
433 | :---: |:---: |:---: |:---: |:---: |
434 | [astalker](https://github.com/astalker) |[valgreens](https://github.com/valgreens) |[bitdeli-chef](https://github.com/bitdeli-chef) |[dchest](https://github.com/dchest) |[gsamokovarov](https://github.com/gsamokovarov) |
435 |
436 | [](https://github.com/ntaoo) |[](https://github.com/hermankan) |[](https://github.com/jesselpalmer) |[](https://github.com/capaj) |[](https://github.com/jordanyee) |
437 | :---: |:---: |:---: |:---: |:---: |
438 | [ntaoo](https://github.com/ntaoo) |[hermankan](https://github.com/hermankan) |[jesselpalmer](https://github.com/jesselpalmer) |[capaj](https://github.com/capaj) |[jordanyee](https://github.com/jordanyee) |
439 |
440 | [](https://github.com/nacyot) |[](https://github.com/kirstein) |[](https://github.com/mo-gr) |[](https://github.com/cryptojuice) |[](https://github.com/olov) |
441 | :---: |:---: |:---: |:---: |:---: |
442 | [nacyot](https://github.com/nacyot) |[kirstein](https://github.com/kirstein) |[mo-gr](https://github.com/mo-gr) |[cryptojuice](https://github.com/cryptojuice) |[olov](https://github.com/olov) |
443 |
444 | [](https://github.com/vorktanamobay) |[](https://github.com/thomastuts) |[](https://github.com/grapswiz) |[](https://github.com/coderhaoxin) |[](https://github.com/dreame4) |
445 | :---: |:---: |:---: |:---: |:---: |
446 | [vorktanamobay](https://github.com/vorktanamobay) |[thomastuts](https://github.com/thomastuts) |[grapswiz](https://github.com/grapswiz) |[coderhaoxin](https://github.com/coderhaoxin) |[dreame4](https://github.com/dreame4) |
447 |
--------------------------------------------------------------------------------
/README-es-es.md:
--------------------------------------------------------------------------------
1 | #Introducción
2 |
3 | El objetivo de esta guía de estilo es presentar un conjunto de buenas prácticas y reglas de estilo para una aplicación de AngularJS.
4 | Estas buenas prácticas están recogidas de:
5 |
6 | 0. Código fuente de AngularJS
7 | 0. Código fuente de artículos que he leído
8 | 0. Mi propia experiencia
9 |
10 | **Nota**: esto es un borrador de la guía de estilo, el principal objetivo es que lo dirija la comunidad, asi que será agradecido por la comunidad si se van añadiendo las cosas que faltan.
11 |
12 | En esta guía de estilo no encontrarás pautas comunes para el desarrollo en Javascript. Esas las podrás encontrar en:
13 |
14 | 0. [Google's JavaScript style guide](https://google.github.io/styleguide/javascriptguide.xml)
15 | 0. [Mozilla's JavaScript style guide](https://developer.mozilla.org/en-US/docs/Developer_Guide/Coding_Style)
16 | 0. [Douglas Crockford's JavaScript style guide](http://javascript.crockford.com/code.html)
17 |
18 | Para el desarrollo de AngularJS la recomendada es [Guía de estilo de Javascript de Google](https://google.github.io/styleguide/javascriptguide.xml).
19 |
20 | En la wiki de Github de AngularJS hay una sección similar por [ProLoser](https://github.com/ProLoser), puedes verla [aquí](https://github.com/angular/angular.js/wiki).
21 |
22 | #Tabla de contenido
23 | * [General](#general)
24 | * [Estructura de directorios](#estructura-de-directorios)
25 | * [Optimiza el ciclo digest](#optimiza-el-ciclo-digest)
26 | * [Otros](#others)
27 | * [Módulos](#modulos)
28 | * [Controladores](#controladores)
29 | * [Directivas](#directivas)
30 | * [Filtros](#filtros)
31 | * [Servicios](#servicios)
32 | * [Plantillas](#plantillas)
33 | * [Enrutamiento](#enrutamiento)
34 |
35 | #General
36 |
37 | ## Estructura de directorios
38 |
39 | Como una aplicación grande de AngularJS tiene muchos componentes, lo mejor es estructurarlos con una jerarquía de directorios.
40 | Principalmente hay dos maneras de hacerlo:
41 |
42 | * Creando una division de alto nivel por tipos de componentes y por funcionalidad a menor nivel.
43 |
44 | De esta manera la estructura de directorios sería así:
45 |
46 | .
47 | ├── app
48 | │ ├── app.js
49 | │ ├── controllers
50 | │ │ ├── page1
51 | │ │ │ ├── FirstCtrl.js
52 | │ │ │ └── SecondCtrl.js
53 | │ │ └── page2
54 | │ │ └── ThirdCtrl.js
55 | │ ├── directives
56 | │ │ ├── page1
57 | │ │ │ └── directive1.js
58 | │ │ └── page2
59 | │ │ ├── directive2.js
60 | │ │ └── directive3.js
61 | │ ├── filters
62 | │ │ ├── page1
63 | │ │ └── page2
64 | │ └── services
65 | │ ├── CommonService.js
66 | │ ├── cache
67 | │ │ ├── Cache1.js
68 | │ │ └── Cache2.js
69 | │ └── models
70 | │ ├── Model1.js
71 | │ └── Model2.js
72 | ├── lib
73 | └── test
74 |
75 | * Creando una division de alto nivel por funcionalidad y por tipos de componentes a bajo nivel.
76 |
77 | Esta es su estructura:
78 |
79 | .
80 | ├── app
81 | │ ├── app.js
82 | │ ├── common
83 | │ │ ├── controllers
84 | │ │ ├── directives
85 | │ │ ├── filters
86 | │ │ └── services
87 | │ ├── page1
88 | │ │ ├── controllers
89 | │ │ │ ├── FirstCtrl.js
90 | │ │ │ └── SecondCtrl.js
91 | │ │ ├── directives
92 | │ │ │ └── directive1.js
93 | │ │ ├── filters
94 | │ │ │ ├── filter1.js
95 | │ │ │ └── filter2.js
96 | │ │ └── services
97 | │ │ ├── service1.js
98 | │ │ └── service2.js
99 | │ └── page2
100 | │ ├── controllers
101 | │ │ └── ThirdCtrl.js
102 | │ ├── directives
103 | │ │ ├── directive2.js
104 | │ │ └── directive3.js
105 | │ ├── filters
106 | │ │ └── filter3.js
107 | │ └── services
108 | │ └── service3.js
109 | ├── lib
110 | └── test
111 |
112 | * Cuando se crean directivas puede resultar útil poner todos los archivos relacionados (plantillas, archivos CSS/SASS, Javascript) en el mismo directorio. Si eliges usar este método se consistente y úsalo en todo tu proyecto.
113 |
114 | app
115 | └── directives
116 | ├── directive1
117 | │ ├── directive1.html
118 | │ ├── directive1.js
119 | │ └── directive1.sass
120 | └── directive2
121 | ├── directive2.html
122 | ├── directive2.js
123 | └── directive2.sass
124 |
125 | Este método se puede combinar con cualquiera de las dos estructuras de arriba.
126 | * Otra pequeña variación en ambas estructuras de directorios es la usada en [ng-boilerplate](http://joshdmiller.github.io/ng-boilerplate/#/home). En ella los test unitarios para el componente se colocan en el lugar donde está el componente. De esta manera puedes realizar cambios en los componentes y es más fácil de encontrar sus tests. Los tests también se pueden usar como documentación y mostrar casos de uso.
127 |
128 | services
129 | ├── cache
130 | │ ├── cache1.js
131 | │ └── cache1.spec.js
132 | └── models
133 | ├── model1.js
134 | └── model1.spec.js
135 |
136 | * El archivo `app.js` contiene la definición de rutas, configuración y/o arranque manual (si es necesario).
137 | * Cada archivo Javascript debe contener un único componente. El archivo debería tener el mismo nombre que el componente.
138 | * Usa una plantilla para el proyecto de Angular como [Yeoman](http://yeoman.io), [ng-boilerplate](http://joshdmiller.github.io/ng-boilerplate/#/home).
139 |
140 | Yo prefiero la primera estructura porque es más fácil de encontrar los componentes comunes.
141 |
142 | La manera de nombrar a los componentes están en la sección de cada componente.
143 |
144 | ## Optimiza el ciclo digest
145 |
146 | * Observa solo las variables más importantes (por ejemplo: cuando usas comunicación en tiempo real, no fuerces un ciclo `$digest` en cada mensaje recibido).
147 | * Las operaciones en`$watch` deben ser lo más simples posible. Realizar operaciones pesadas y lentas en un simple `$watch` puede ralentizar la aplicacion entera (el ciclo $digest se hace en un unico hilo debido al funcionamiento de Javascript con un único hilo de ejecución).
148 |
149 | ## Otros
150 |
151 | * Usa:
152 | * `$timeout` en lugar de `setTimeout`
153 | * `$window` en lugar de `window`
154 | * `$document` en lugar de `document`
155 | * `$http` en lugar de `$.ajax`
156 |
157 | Esto hará que sea más fácil de testear y, en algunos casos, prevenir comportamientos extraños (por ejemplo, olvidar usar `$scope.$apply` en `setTimeout`).
158 |
159 | * Automatiza tu flujo de trabajo usando herramientas como:
160 | * [Yeoman](http://yeoman.io)
161 | * [Grunt](http://gruntjs.com)
162 | * [Bower](http://bower.io)
163 |
164 | * Usa promesas (`$q`) en lugar de callbacks. Hará que tu código parezca más limpio y elegante y te salvará del infierno de callbacks anidadas.
165 | * Usa `$resource` en lugar de `$http` cuando puedas. Un nivel alto de abstracción evita la redundancia.
166 | * Usa un pre-minifier de AngularJS (como [ngmin](https://github.com/btford/ngmin) or [ng-annotate](https://github.com/olov/ng-annotate)) para prevenir problemas después de minificar.
167 | * No utilices variables globales. Solventa todas tus dependencias usando la inyección de dependencias.
168 | * No ensucies el `$scope`. Solamente añade funciones que van a ser usadas en las plantillas.
169 |
170 | #Modulos
171 |
172 | Hay dos maneras de estructurar los módulos:
173 |
174 | 0. Por funcionalidad
175 | 0. Por tipo de componente
176 |
177 | Actualmente no hay gran diferencia, pero la primera manera parece más limpia. También si se implementa la carga asíncrona de módulos (todavía no está en el roadmap de AngularJS), mejoraría el rendimiento de la aplicación.
178 |
179 | #Controladores
180 |
181 | * No modifiques el DOM desde tus controladores. Utiliza directivas para eso.
182 | * El nombre del controlador se basa en su funcionalidad (por ejemplo carrito de compra, página principal, panel de administración) y la subcadena `Ctrl` al final. Los controladores se nombran con UpperCamelCase (`HomePageCtrl`, `ShoppingCartCtrl`, `AdminPanelCtrl`, etc.).
183 | * Los controladores no se deben definir como variables globales (no importa que AngularJS lo permita, ensuciar el espacio global es una mala práctica).
184 | * Utiliza la sintaxis de arrays para definir controladores:
185 |
186 |
187 |
188 | module.controller('MyCtrl', ['dependency1', 'dependency2', ..., 'dependencyn', function (dependency1, dependency2, ..., dependencyn) {
189 | //...body
190 | }]);
191 |
192 |
193 | Usando este tipo de definición se evitan problemas con la minificación. Puedes generar automáticamente esta definición en vez de la estándar con herramientas como [ng-annotate](https://github.com/olov/ng-annotate) (y la tarea de grunt [grunt-ng-annotate](https://github.com/mzgol/grunt-ng-annotate)).
194 | * Utiliza los nombres originales de las dependencias del controlador. Esto te permitirá escribir código más legible:
195 |
196 |
197 |
198 | module.controller('MyCtrl', ['$scope', function (s) {
199 | //...body
200 | }]);
201 |
202 |
203 | es menos fácil de leer que:
204 |
205 |
206 | module.controller('MyCtrl', ['$scope', function ($scope) {
207 | //...body
208 | }]);
209 |
210 |
211 | Esto se aplica especialmente en archivos en los que hay mucho código y tengas hacer scroll porque que olvides que variable hace referencia a cada dependencia.
212 |
213 | * Haz los controladores lo mas sencillos posibles. Abstrae las funciones comunes que uses en un servicio.
214 | * Comunica diferentes controladores usando la invocación de métodos (es posible cuando los controladores hijos quieren comunicarse con los controladores padre) o los métodos `$emit`, `$broadcast` y `$on`. La emisión y broadcast de mensajes debería hacerse lo menos posible.
215 | * Haz una lista de todos los mensajes que son mandados con `$emit`, `$broadcast` y manejalos con cuidado para evitar colisiones de nombres y posibles bugs.
216 | * Cuando necesites formatear datos encapsula la lógica en un [filtro](#filtros) y decláralo como dependencia:
217 |
218 |
219 | module.filter('myFormat', function () {
220 | return function () {
221 | //body...
222 | };
223 | });
224 |
225 | module.controller('MyCtrl', ['$scope', 'myFormatFilter', function ($scope, myFormatFilter) {
226 | //body...
227 | }]);
228 |
229 | #Directivas
230 |
231 | * Nombra tus directivas con lowerCamelCase.
232 | * Usa `scope` en lugar de `$scope` en tu funcion link. En el compilado, ya están definidos los argumentos de las funciones post/pre link cuando son invocadas, no los podrás cambiar después usando la inyección de dependencias. Este estilo es usado también en el código fuente de AngularJS.
233 | * Usa prefijos personalizados para las directivas para prevenir colisiones de nombres con librerías externas.
234 | * No uses los prefijos `ng` o `ui` porque están reservados para uso de AngularJS y AngularJS UI.
235 | * La manipulación del DOM solo se debe hacer mediante directivas.
236 | * Crea un scope aislado cuando desarrollas componentes reusables.
237 |
238 | #Filtros
239 |
240 | * Nombra tus filtros usando lowerCamelCase.
241 | * Haz tus filtros lo más ligeros posibles. Estos son llamados a menudo durante el ciclo `$digest` asi que un filtro lento puede hacer lenta tu aplicación.
242 |
243 | #Servicios
244 |
245 | * Utiliza camelCase (con mayúscula o minúscula) para darle nombre a tus servicios.
246 | * Encapsula la lógica de negocio en los servicios.
247 | * Los servicios que encapsulan la lógica de negocio son preferibles como `service` en lugar de `factory`
248 | * Para cachear a nivel de sesión puedes usar `$cacheFactory`. Se debería usar para cachear resultados de peticiones o procesos pesados.
249 |
250 | #Plantillas
251 |
252 | * Utiliza `ng-bind` o `ng-cloak` en lugar de `{{ }}` para prevenir mostrar contenido sin compilar.
253 | * Evita escribir código complejo en la plantilla.
254 | * Cuando necesites asignar el `src` de una imagen dinamicamente usa `ng-src` en lugar de `src` con `{{}}`.
255 | * En lugar de usar variables del scope como cadenas en el atributo `style` con `{{ }}`, usa la directiva `ng-style` con los parametros como claves de un objeto y las variables del scope como valores:
256 |
257 | ...
258 | $scope.divStyle = {
259 | width: 200,
260 | position: 'relative'
261 | };
262 | ...
263 |
264 | my beautifully styled div which will work in IE
;
265 |
266 | #Enrutamiento
267 |
268 | * Usa `resolve` para resolver dependencias antes de que la vista se muestre.
269 |
--------------------------------------------------------------------------------
/README-fr-fr.md:
--------------------------------------------------------------------------------
1 | # Introduction
2 |
3 | Ce guide est la traduction francaise de [AngularJS style guide](https://github.com/mgechev/angularjs-style-guide).
4 |
5 | Le but de ce guide de style est d'exposer un ensemble de meilleures pratiques et directives de style pour une application AngularJS.
6 | Elles proviennent:
7 |
8 | 0. du code source d'AngularJS
9 | 0. du code source ou des articles que j'ai lus
10 | 0. de ma propre expérience.
11 |
12 | **Note 1**: ce guide est encore à l'état d'ébauche. Son principal objectif est d'être développé par la communauté, donc combler les lacunes sera grandement apprécié par l'ensemble de la communauté.
13 |
14 | **Note 2**: avant de suivre certaines directives des traductions du document original en anglais, assurez-vous qu'elles sont à jour avec la [dernière version](https://github.com/mgechev/angularjs-style-guide/blob/master/README.md).
15 |
16 | Dans ce document, vous ne trouverez pas de directives générales concernant le développement en JavaScript. Vous pouvez les trouver dans les documents suivants:
17 |
18 | 0. [Google's JavaScript style guide](https://google.github.io/styleguide/javascriptguide.xml)
19 | 0. [Mozilla's JavaScript style guide](https://developer.mozilla.org/en-US/docs/Developer_Guide/Coding_Style)
20 | 0. [Douglas Crockford's JavaScript style guide](http://javascript.crockford.com/code.html)
21 | 0. [Airbnb JavaScript style guide](https://github.com/airbnb/javascript)
22 |
23 | Pour le développement d'AngularJS, le guide recommandé est [Google's JavaScript style guide](https://google.github.io/styleguide/javascriptguide.xml).
24 |
25 | Dans le wiki Github d'AngularJS, il y a une section similaire de [ProLoser](https://github.com/ProLoser), vous pouvez la consulter [ici](https://github.com/angular/angular.js/wiki).
26 |
27 | # Table des matières
28 |
29 | * [Général](#général)
30 | * [Arborescence](#arborescence)
31 | * [Balisage](#balisage)
32 | * [Conventions de nommage](#convention-de-nommage)
33 | * [Autres](#autres)
34 | * [Modules](#modules)
35 | * [Contrôleurs](#contrôleurs)
36 | * [Directives](#directives)
37 | * [Filtres](#filtres)
38 | * [Services](#services)
39 | * [Gabarits](#gabarits)
40 | * [Routage](#routage)
41 | * [Tests E2E](#tests-e2e)
42 | * [i18n](#i18n)
43 | * [Performance](#performance)
44 | * [Contribution](#contribution)
45 |
46 | # Général
47 |
48 | ## Arborescence
49 |
50 | Étant donné qu'une grosse application AngularJS a beaucoup de composants, il est préférable de la structurer en une hiérarchie de répertoires.
51 | Il existe deux approches principales:
52 |
53 | * Créer une division de haut niveau par types de composants et une division inférieure par fonctionnalité.
54 |
55 | De cette façon, la structure de répertoires ressemblera à:
56 |
57 | ```
58 | .
59 | ├── app
60 | │ ├── app.js
61 | │ ├── controllers
62 | │ │ ├── home
63 | │ │ │ ├── FirstCtrl.js
64 | │ │ │ └── SecondCtrl.js
65 | │ │ └── about
66 | │ │ └── ThirdCtrl.js
67 | │ ├── directives
68 | │ │ ├── home
69 | │ │ │ └── directive1.js
70 | │ │ └── about
71 | │ │ ├── directive2.js
72 | │ │ └── directive3.js
73 | │ ├── filters
74 | │ │ ├── home
75 | │ │ └── about
76 | │ └── services
77 | │ ├── CommonService.js
78 | │ ├── cache
79 | │ │ ├── Cache1.js
80 | │ │ └── Cache2.js
81 | │ └── models
82 | │ ├── Model1.js
83 | │ └── Model2.js
84 | ├── partials
85 | ├── lib
86 | └── test
87 | ```
88 |
89 | * Créer une division de haut niveau par fonctionnalité et de niveau inférieur par type de composants.
90 |
91 | Voici son schéma:
92 |
93 | ```
94 | .
95 | ├── app
96 | │ ├── app.js
97 | │ ├── common
98 | │ │ ├── controllers
99 | │ │ ├── directives
100 | │ │ ├── filters
101 | │ │ └── services
102 | │ ├── home
103 | │ │ ├── controllers
104 | │ │ │ ├── FirstCtrl.js
105 | │ │ │ └── SecondCtrl.js
106 | │ │ ├── directives
107 | │ │ │ └── directive1.js
108 | │ │ ├── filters
109 | │ │ │ ├── filter1.js
110 | │ │ │ └── filter2.js
111 | │ │ └── services
112 | │ │ ├── service1.js
113 | │ │ └── service2.js
114 | │ └── about
115 | │ ├── controllers
116 | │ │ └── ThirdCtrl.js
117 | │ ├── directives
118 | │ │ ├── directive2.js
119 | │ │ └── directive3.js
120 | │ ├── filters
121 | │ │ └── filter3.js
122 | │ └── services
123 | │ └── service3.js
124 | ├── partials
125 | ├── lib
126 | └── test
127 | ```
128 |
129 | * Dans l'éventualité ou le nom du dossier contient plusieurs mots, utilisez la syntaxe lisp-case comme suit:
130 |
131 | ```
132 | app
133 | ├── app.js
134 | └── mon-module-complexe
135 | ├── controllers
136 | ├── directives
137 | ├── filters
138 | └── services
139 |
140 | ```
141 |
142 | * Lors de la création de directives, placez tous les fichiers associés à une directive (gabarits, fichiers CSS / SASS, JavaScript) dans un seul dossier. Si vous choisissez d'utiliser ce style d'arborescence, soyez cohérent et utilisez-le partout dans votre projet.
143 |
144 | ```
145 | app
146 | └── directives
147 | ├── directive1
148 | │ ├── directive1.html
149 | │ ├── directive1.js
150 | │ └── directive1.sass
151 | └── directive2
152 | ├── directive2.html
153 | ├── directive2.js
154 | └── directive2.sass
155 | ```
156 |
157 | Cette approche peut être combinée avec les deux structures de répertoires ci-dessus.
158 |
159 | * Une dernière petite variation des deux structures de répertoires est celle utilisée dans [ng-boilerplate](http://joshdmiller.github.io/ng-boilerplate/#/home). Dans celle-ci, les tests unitaires pour un composant donné sont dans le même dossier que le composant. De cette façon, quand vous modifiez un composant donné, il est facile de trouver ses tests. Les tests tiennent aussi lieu de documentation et démontrent des cas d'usage.
160 |
161 | ```
162 | services
163 | ├── cache
164 | │ ├── cache1.js
165 | │ └── cache1.spec.js
166 | └── models
167 | ├── model1.js
168 | └── model1.spec.js
169 | ```
170 |
171 | * Le fichier `app.js` devrait contenir la définition des routes, la configuration et/ou l'amorçage manuel (si nécessaire).
172 | * Chaque fichier JavaScript ne devrait contenir qu'un seul composant. Le fichier doit être nommé avec le nom du composant.
173 | * Utilisez un modèle de structure de projet pour Angular tel que [Yeoman](http://yeoman.io) ou [ng-boilerplate](http://joshdmiller.github.io/ng-boilerplate/#/home).
174 |
175 | Les conventions sur le nommage des composants peuvent être trouvées dans la section de chaque composant.
176 |
177 | ## Balisage
178 |
179 | [TLDR;](http://developer.yahoo.com/blogs/ydn/high-performance-sites-rule-6-move-scripts-bottom-7200.html) Placer les scripts tout en bas.
180 |
181 | ```
182 |
183 |
184 |
185 |
186 | MyApp
187 |
188 |
189 |
192 |
193 |
194 |
195 |
196 | ```
197 |
198 | Garder les choses simples et placez les directives spécifiques d'AngularJS en dernier, après les attributs HTML standard. De cette façon, il sera plus facile de parcourir votre code et de le maintenir puisque vos attributs seront groupés et positionnés de manière cohérente et régulière.
199 |
200 | ```html
201 |
206 | ```
207 |
208 | Les autres attributs HTML devraient suivre les recommandations du [Code Guide](http://mdo.github.io/code-guide/#html-attribute-order) de Mark Otto.
209 |
210 | ## Conventions de nommage
211 | The tableau suivant présente des conventions de nommage pour chaque élément:
212 |
213 | Élément | Style de nommage | Exemple | Usage
214 | ----|------|----|--------
215 | Modules | lowerCamelCase | angularApp |
216 | Contrôleurs | Fonctionnalité + 'Ctrl' | AdminCtrl |
217 | Directives | lowerCamelCase | userInfo |
218 | Filtres | lowerCamelCase | userFilter |
219 | Services | UpperCamelCase | User | constructor
220 | Factories | lowerCamelCase | dataFactory | autres
221 |
222 | ## Autres
223 |
224 | * Utilisez:
225 | * `$timeout` au lieu de `setTimeout`
226 | * `$interval` au lieu de `setInterval`
227 | * `$window` au lieu de `window`
228 | * `$document` au lieu de `document`
229 | * `$http` au lieu de `$.ajax`
230 | * `$location` au lieur de `window.location`ou `$window.location`
231 | * `$cookies` au lieu de `document.cookie`
232 |
233 | Cela rendra vos tests plus facile à faire et, dans certains cas, évitera les comportements inattendus (par exemple, si vous avez oublié `$scope.$apply` dans `setTimeout`).
234 |
235 | * Automatisez votre flux de travail en utilisant des outils comme:
236 | * [NPM](https://www.npmjs.com/)
237 | * [Grunt](http://gruntjs.com)
238 | * [Gulp](http://gulpjs.com)
239 | * [Yeoman](http://yeoman.io)
240 | * [Bower](http://bower.io)
241 |
242 | * Utilisez des promises (`$q`) au lieu de rappels (callback). Cela rendra votre code plus élégant et propre, et vous sauvera de l'enfer des callbacks.
243 | * Utilisez `$resource` au lieu de `$http` lorsque possible. Un niveau d'abstraction plus élevé diminuera la redondance.
244 | * Utilisez un pré-minifier AngularJS ([ng-annotate](https://github.com/olov/ng-annotate)) pour la prévention des problèmes après minification.
245 | * N'utilisez pas de variables globales. Résolvez toutes les dépendances en utilisant l'injection de dépendances, cela préviendra les bugs et le monkey-patching lorsqu'en phase de test.
246 | * Eliminez les variables globales en utilisant Grunt/Gulp pour englober votre code dans des Expressions de Fonction Immédiatement Invoquée (Immediately Invoked Function Expression, (IIFE)). Vous pouvez utiliser des plugins tel que [grunt-wrap](https://www.npmjs.com/package/grunt-wrap) ou [gulp-wrap](https://www.npmjs.com/package/gulp-wrap/) pour cet usage. Exemple (avec Gulp)
247 |
248 | ```Javascript
249 | gulp.src("./src/*.js")
250 | .pipe(wrap('(function(){\n"use strict";\n<%= contents %>\n})();'))
251 | .pipe(gulp.dest("./dist"));
252 | ```
253 | * Ne polluez pas votre portée `$scope`. Ajoutez uniquement sur celle-ci les fonctions et les variables qui sont utilisés dans les gabarits.
254 | * Préférez l'utilisation de [contrôleurs au lieu de `ngInit`](https://github.com/angular/angular.js/commit/010d9b6853a9d2718b095e4c017c9bd5f135e0b0). Il n'y a que quelques utilisations appropriées de ngInit tel que pour spécifier des propriétés spécifiques de ngRepeat, et pour injecter des données via des scripts côté serveur. Outre ces quelques cas, vous devez utiliser les contrôleurs plutôt que `ngInit` pour initialiser les valeurs sur une portée. L'expression passée à `ngInit` doit être analysée et évaluée par l'interpréteur d'Angular implémenté dans le service `$parse`. Ceci mène à:
255 | - Des impacts sur la performance, car l'interpréteur est implémenté en JavaScript
256 | - La mise en cache des expressions passées au service `$parse` n'a pas réellement de sens dans la plus part des cas, étant donnée que l'expression `ngInit` n'est évaluée qu'une seule fois
257 | - Ecrire des chaînes de caractère dans votre HTML est enclin à causer des erreurs, puisqu'il n'y a pas d'auto-complétion ou de support par votre éditeur de texte
258 | - Aucune levée d'exceptions à l'éxécution
259 | * Ne pas utiliser le prefixe `$` pour les noms de variables, les propriétés et les méthodes. Ce préfixe est réservé à l'usage d'AngularJS.
260 | * Lors de la résolution des dépendances par le système d'injection de dépendances d'AngularJS, triez les dépendances par leur type - les dépendances intégrées à AngularJS en premier, suivies des vôtres :
261 |
262 | ```javascript
263 | module.factory('Service', function ($rootScope, $timeout, MyCustomDependency1, MyCustomDependency2) {
264 | return {
265 | //Something
266 | };
267 | });
268 | ```
269 |
270 | # Modules
271 |
272 | * Les modules devraient être nommés en lowerCamelCase. Pour indiquer que le module `b` est un sous-module du module `a`, vous pouvez les imbriquer en utlisant un espace de noms tel que `a.b`.
273 |
274 | Les deux façons habituelles de structurer les modules sont:
275 |
276 | 0. par fonctionnalité
277 | 0. par type de composant.
278 |
279 | Actuellement, il n'y a pas une grande différence entre les deux mais la première semble plus propre. En outre, si le chargement paresseux des modules est implémenté (actuellement il ne figure pas sur la feuille de route d'AngularJS), il permettra d'améliorer les performances de l'application.
280 |
281 | # Contrôleurs
282 |
283 | * Ne manipulez pas le DOM dans vos contrôleurs. Cela rendra vos contrôleurs plus difficiles à tester et violerait le [principe de séparation des préoccupations](https://en.wikipedia.org/wiki/Separation_of_concerns). Utilisez plutôt les directives.
284 | * Le nom d'un contrôleur s'obtient à partir de sa fonction (par exemple panier, page d'accueil, panneau d'administration) suffixée par `Ctrl`.
285 | * Les contrôleurs sont des [constructeurs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor) javascript ordinaires, ils sont donc nommés en UpperCamelCase (`HomePageCtrl`, `ShoppingCartCtrl`, `AdminPanelCtrl`, etc.)
286 | * Les contrôleurs ne devraient pas être définis dans le contexte global (bien qu'AngularJS le permet, c'est une mauvaise pratique de polluer l'espace de noms global).
287 | * Utilisez la syntaxe suivante pour définir des contrôleurs:
288 |
289 | ```JavaScript
290 | function MyCtrl(dependency1, dependency2, ..., dependencyn) {
291 | // ...
292 | }
293 | module.controller('MyCtrl', MyCtrl);
294 | ```
295 |
296 | Une telle définition évite les problèmes avec la minification. Vous pouvez générer automatiquement la définition du tableau à l'aide d'outils comme [ng-annotate](https://github.com/olov/ng-annotate) (et la tâche grunt [grunt-ng-annotate](https://github.com/mzgol/grunt-ng-annotate)).
297 |
298 | Une autre alternative serait d'utiliser `$inject` comme suit:
299 |
300 | ```JavaScript
301 | angular
302 | .module('app')
303 | .controller('HomepageCtrl', Homepage);
304 |
305 | HomepageCtrl.$inject = ['$log', '$http', 'ngRoute'];
306 |
307 | function HomepageCtrl($log, $http, ngRoute) {
308 | // ...
309 | }
310 | ```
311 |
312 | * Utilisez les noms d'origine des dépendances du contrôleur. Cela vous aidera à produire un code plus lisible:
313 |
314 | ```JavaScript
315 | module.controller('MyCtrl', ['$scope', function (s) {
316 | //...body
317 | }]);
318 | ```
319 |
320 | est moins lisible que
321 |
322 | ```JavaScript
323 | module.controller('MyCtrl', ['$scope', function ($scope) {
324 | //...body
325 | }]);
326 | ```
327 |
328 | Cela s'applique particulièrement à un fichier qui a tellement de lignes de code que vous devrez les faire défiler. Cela pourrait vous faire oublier quelle variable est liée à quelle dépendance.
329 |
330 | * Faites les contrôleurs aussi simples que possible. Extrayez les fonctions couramment utilisées dans un service.
331 | * Communiquez entre les différents contrôleurs en utilisant l'appel de méthode (possible lorsqu'un enfant veut communiquer avec son parent) ou `$emit`, `$broadcast` et `$on`. Les messages émis et diffusés doivent être réduits au minimum.
332 | * Faites une liste de tous les messages qui sont passés en utilisant `$emit` et `$broadcast`, et gérez-la avec précaution à cause des conflits de nom et bugs éventuels.
333 | Exemple:
334 |
335 | ```JavaScript
336 | // app.js
337 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
338 | Custom events:
339 | - 'authorization-message' - description of the message
340 | - { user, role, action } - data format
341 | - user - a string, which contains the username
342 | - role - an ID of the role the user has
343 | - action - specific ation the user tries to perform
344 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
345 | ```
346 | * Si vous devez formater les données alors encapsulez la logique de mise en forme dans un [filtre](#filtres) et déclarez-le comme dépendance:
347 |
348 | ```JavaScript
349 | module.filter('myFormat', function () {
350 | return function () {
351 | //body...
352 | };
353 | });
354 |
355 | module.controller('MyCtrl', ['$scope', 'myFormatFilter', function ($scope, myFormatFilter) {
356 | //body...
357 | }]);
358 | ```
359 |
360 | * Il est préférable d'utiliser la syntaxe `controller as`:
361 |
362 | ```
363 |
364 | {{ main.title }}
365 |
366 | ```
367 |
368 | ```JavaScript
369 | app.controller('MainCtrl', MainCtrl);
370 |
371 | function MainCtrl () {
372 | this.title = 'Some title';
373 | }
374 | ```
375 |
376 | Les principales avantages d'utiliser cette syntaxe:
377 | * Créer des composants isolés - les propriétés liées ne font pas parties de la chaîne de prototypage de `$scope`. C'est une bonne pratique depuis que l'héritage du prototype de `$scope` a quelques inconvénients majeurs (c'est probablement la raison pour laquelle il serat supprimé d'Angular 2):
378 | * Il est difficile de suivre la trace des données pour savoir où elles vont.
379 | * Le changement de valeur d'un scope peut affecter certaines portées de façon inattendue.
380 | * Plus difficile à réusiner (refactoring).
381 | * La règle des points : '[dot rule(in English)](http://jimhoskins.com/2012/12/14/nested-scopes-in-angularjs.html)'.
382 | * Ne pas utiliser `$scope` sauf pour le besoin d'opérations spéciales (comme `$scope.$broadcast`) est une bonne preparation pour AngularJS V2.
383 | * La syntaxe est plus proche du constructeur Javascript brut ('vanilla').
384 |
385 | Decouvrez la syntaxe `controller as` en détail: [adoptez-la-syntaxe-controller-as](http://www.occitech.fr/blog/2014/06/adoptez-la-syntaxe-controller-as-angularjs/)
386 |
387 | * Eviter d'écrire la logique métier dans le contrôleur. Déplacez la logique métier dans un `modèle`, grâce à un service.
388 | Par exemple:
389 |
390 | ```Javascript
391 | //Ceci est un comportement répandu (mauvais exemple) d'utiliser le contrôleur pour implémenter la logique métier.
392 | angular.module('Store', [])
393 | .controller('OrderCtrl', function ($scope) {
394 |
395 | $scope.items = [];
396 |
397 | $scope.addToOrder = function (item) {
398 | $scope.items.push(item);//-->Logique métier dans le contrôleur
399 | };
400 |
401 | $scope.removeFromOrder = function (item) {
402 | $scope.items.splice($scope.items.indexOf(item), 1);//-->Logique métier dans le contrôleur
403 | };
404 |
405 | $scope.totalPrice = function () {
406 | return $scope.items.reduce(function (memo, item) {
407 | return memo + (item.qty * item.price);//-->Logique métier dans le contrôleur
408 | }, 0);
409 | };
410 | });
411 | ```
412 |
413 | Quand on utilise un service comme 'modèle' pour implémenter la logique métier, voici à quoi ressemble le contrôleur (voir 'utilisez un service comme votre Modèle' pour une implémentation d'un service-modèle):
414 |
415 | ```Javascript
416 | //Order est utilisé comme un 'modèle'
417 | angular.module('Store', [])
418 | .controller('OrderCtrl', function (Order) {
419 |
420 | $scope.items = Order.items;
421 |
422 | $scope.addToOrder = function (item) {
423 | Order.addToOrder(item);
424 | };
425 |
426 | $scope.removeFromOrder = function (item) {
427 | Order.removeFromOrder(item);
428 | };
429 |
430 | $scope.totalPrice = function () {
431 | return Order.total();
432 | };
433 | });
434 | ```
435 |
436 | Pourquoi la mise en place de la logique métier dans le contrôleur est une mauvaise pratique ?
437 | * Les contrôleurs sont instanciés pour chaque vue HTML et sont détruits au déchargement de la vue.
438 | * Les contrôleurs ne sont pas ré-utilisables - ils sont liés à la vue HTML.
439 | * Les contrôleurs ne sont pas destinés à êtres injectés.
440 |
441 | * Dans le cas de contrôleurs imbriqués utilisez les portées emboitées (avec `controllerAs`):
442 |
443 | **app.js**
444 | ```javascript
445 | module.config(function ($routeProvider) {
446 | $routeProvider
447 | .when('/route', {
448 | templateUrl: 'partials/template.html',
449 | controller: 'HomeCtrl',
450 | controllerAs: 'home'
451 | });
452 | });
453 | ```
454 | **HomeCtrl**
455 | ```javascript
456 | function HomeCtrl() {
457 | this.bindingValue = 42;
458 | }
459 | ```
460 | **template.html**
461 | ```
462 |
463 | ```
464 |
465 | # Directives
466 |
467 | * Nommez vos directives en lowerCamelCase
468 | * Utilisez `scope` au lieu de `$scope` dans votre fonction de lien. Dans la compilation, les fonctions de liaison pré/post compilation, vous avez déjà les arguments qui sont passés lorsque la fonction est appelée, vous ne serez pas en mesure de les modifier à l'aide de DI. Ce style est également utilisé dans le code source d'AngularJS.
469 | * Utilisez les préfixes personnalisés pour vos directives pour éviter les collisions de noms de bibliothèques tierces.
470 | * Ne pas utiliser `ng` ou `ui` comme préfixe car ils sont réservés pour AngularJS et l'utilisation d'AngularJS UI.
471 | * Les manipulations du DOM doivent être effectués uniquement avec des directives.
472 | * Créer un scope isolé lorsque vous développez des composants réutilisables.
473 | * Utilisez des directives comme des attributs ou des éléments au lieu de commentaires ou de classes, cela va rendre le code plus lisible.
474 | * Utilisez `$scope.$on('$destroy, fn)` pour le nettoyage de vos objects/variables. Ceci est particulièrement utile lorsque vous utilisez des plugins tiers comme directives.
475 | * Ne pas oublier d'utiliser `$sce` lorsque vous devez faire face à un contenu non approuvé.
476 |
477 | # Filtres
478 |
479 | * Nommez vos filtres en lowerCamelCase.
480 | * Faites vos filtres aussi légers que possible. Ils sont souvent appelés lors de la boucle `$digest`, donc créer un filtre lent ralentira votre application.
481 | * Limitez vos filtres à une seule chose et gardez-les cohérents. Des manipulations plus complexes peuvent être obtenues en enchaînant des filtres existants.
482 |
483 | # Services
484 |
485 | La présente section contient des informations au sujet des composants service dans AngularJS. Sauf mention contraire, elles ne dépendent pas de la méthode utilisée pour définir les services (c.-à-d. `provider`, `factory`, `service`).
486 |
487 | * Nommez vos services en camelCase:
488 | * UpperCamelCase (PascalCase) pour vos services utilisés comme constructeurs, c.-à.-d.:
489 |
490 | ```JavaScript
491 | module.controller('MainCtrl', function ($scope, User) {
492 | $scope.user = new User('foo', 42);
493 | });
494 |
495 | module.factory('User', function () {
496 | return function User(name, age) {
497 | this.name = name;
498 | this.age = age;
499 | };
500 | });
501 | ```
502 |
503 | * lowerCamel pour tous les autres services.
504 |
505 | * Encapsulez la logique métier dans des services.
506 | * La méthode `service` est préférable à la méthode `factory`. De cette façon, nous pouvons profiter de l'héritage classique plus facilement:
507 |
508 | ```JavaScript
509 | function Human() {
510 | //body
511 | }
512 | Human.prototype.talk = function () {
513 | return "I'm talking";
514 | };
515 |
516 | function Developer() {
517 | //body
518 | }
519 | Developer.prototype = Object.create(Human.prototype);
520 | Developer.prototype.code = function () {
521 | return "I'm codding";
522 | };
523 |
524 | myModule.service('Human', Human);
525 | myModule.service('Developer', Developer);
526 |
527 | ```
528 |
529 | * Pour un cache de session, vous pouvez utiliser `$cacheFactory`. Il devrait être utilisé pour mettre en cache les résultats des requêtes ou des calculs lourds.
530 | * Si un service donné nécessite une configuration, définissez le service comme un provider et configurez-le ainsi dans la fonction de rappel `config`:
531 |
532 | ```JavaScript
533 | angular.module('demo', [])
534 | .config(function ($provide) {
535 | $provide.provider('sample', function () {
536 | var foo = 42;
537 | return {
538 | setFoo: function (f) {
539 | foo = f;
540 | },
541 | $get: function () {
542 | return {
543 | foo: foo
544 | };
545 | }
546 | };
547 | });
548 | });
549 |
550 | var demo = angular.module('demo');
551 |
552 | demo.config(function (sampleProvider) {
553 | sampleProvider.setFoo(41);
554 | });
555 | ```
556 |
557 | # Gabarits
558 |
559 | * Utilisez `ng-bind` ou `ng-cloak` au lieu de simples `{{ }}` pour prévenir les collisions de contenus
560 | * Eviter d'écrire du code complexe dans les gabarits
561 | * Quand vous avez besoin de définir le `src` d'une image dynamiquement, utilisez `ng-src` au lieu de `src` avec `{{}}` dans le gabarit. Ceci pour permettre un refresh dynamique ? (NLDT)
562 | * Au lieu d'utiliser la variable $scope en tant que chaîne et de l'utiliser avec l'atribut `style` et `{{}}`, utilisez la directive `ng-style` avec les paramètres de l'objet comme et les variables de scope comme valeurs:
563 |
564 | ```HTML
565 |
573 |
574 | my beautifully styled div which will work in IE
;
575 | ```
576 |
577 | # Routage
578 |
579 | * Utilisez `resolve` pour résoudre les dépendances avant que la vue ne soit affichée.
580 | * Ne placez pas d'appels REST à l'intérieur du callback `resolve`. Isolez les requêtes à l'intérieur
581 | de services appropriés. De cette manière, vous pourrez activer la mise en cache et appliquer le
582 | principe de séparation des problèmes (_separation of concerns_).
583 |
584 | # Tests E2E
585 |
586 | Les tests E2E sont la prochaine étape logique après les tests unitaires. Cette étape permet de retracer les bugs et les erreurs dans le comportement de votre système. Ils confirment que les scénarios les plus communs de l'utilisation de votre application sont fonctionnels. De cette manière, vous pouvez automatiser le processus et l'exécuter à chaque fois que vous déployez votre application.
587 |
588 | Idéallement, les tests E2E Angular sont écris avec Jasmine. Ces tests sont exécutés en utilisant
589 | l'exécuteur de tests Protractor E2E qui utilise des évènements natifs et qui possèdes des
590 | fonctionnalités spécifiques aux applications Angular.
591 |
592 | Arborescence:
593 | ```
594 | .
595 | ├── app
596 | │ ├── app.js
597 | │ ├── home
598 | │ │ ├── home.html
599 | │ │ ├── controllers
600 | │ │ │ ├── FirstCtrl.js
601 | │ │ │ ├── FirstCtrl.spec.js
602 | │ │ ├── directives
603 | │ │ │ └── directive1.js
604 | │ │ │ └── directive1.spec.js
605 | │ │ ├── filters
606 | │ │ │ ├── filter1.js
607 | │ │ │ └── filter1.spec.js
608 | │ │ └── services
609 | │ │ ├── service1.js
610 | │ │ └── service1.spec.js
611 | │ └── about
612 | │ ├── about.html
613 | │ ├── controllers
614 | │ │ └── ThirdCtrl.js
615 | │ │ └── ThirdCtrl.spec.js
616 | │ └── directives
617 | │ ├── directive2.js
618 | │ └── directive2.spec.js
619 | ├── partials
620 | ├── lib
621 | └── e2e-tests
622 | ├── protractor.conf.js
623 | └── specs
624 | ├── home.js
625 | └── about.js
626 | ```
627 |
628 | # i18n
629 |
630 | * Pour les versions les plus récentes du framework (>=1.4.0), utilisez les outils i18n intégrés. Lorsque vous utilisez de versions antérieures(<1.4.0), utilisez [`angular-translate`](https://github.com/angular-translate/angular-translate).
631 |
632 | # Performance
633 |
634 | * Surveiller seulement les variables les plus importantes (par exemple, lors de l'utilisation de communication en temps réel, ne pas provoquer une boucle `$digest` dans chaque message reçu).
635 | * Pour un contenu initialisé une seule fois et qui ensuite ne change pas, utiliser des observateurs à évaluation unique comme [bindonce](https://github.com/Pasvaz/bindonce).
636 | * Faire les calculs dans `$watch` aussi simples que possible. Faire des calculs lourds et lents dans un unique `$watch` va ralentir l'ensemble de l'application (la boucle `$digest` s'exécute dans un seul thread en raison de la nature mono-thread de JavaScript).
637 | * Mettre le troisième paramètre de la fonction `$timeout` à false pour éviter la boucle `$digest` lorsqu'aucune des variables observées n'est impactée par la fonction de rappel `$timeout`.
638 |
639 | # Contribution
640 |
641 | Puisque ce guide de style a pour but d'être un projet communautaire, les contributions sont très appréciées. Par exemple, vous pouvez contribuer en développant la section [Tests](#tests) ou en traduisant le guide dans votre langue.
--------------------------------------------------------------------------------
/README-id-id.md:
--------------------------------------------------------------------------------
1 | # Introduksi
2 |
3 | Tujuan dari panduan ini adalah memberikan standar gaya dan cara-cara terbaik menulis kode untuk sebuah aplikasi AngularJS.
4 | Cara-cara ini dikumpulkan dari:
5 |
6 | 0. Kode sumber AngularJS
7 | 0. Kode-kode atau artikel yang pernah saya baca
8 | 0. Pengalaman saya sendiri
9 |
10 | **Catatan 1**: Panduan ini masih berupa konsep, tujuan utamanya adalah agar dikendalikan oleh komunitas, jadi menyumbangkan waktu anda untuk proyek ini akan sangat dihargai seluruh komunitas.
11 |
12 | **Catatan 2**: Sebelum mengikuti panduan ini, pastikan bahwa panduan ini versi yang terbaru atau sama dengan versi dalam bahasa inggris (bisa anda cek dari waktu commit).
13 |
14 | Dalam panduan ini, anda tidak akan menemukan panduan umum untuk menulis kode javascript. Seperti yang bisa anda temukan di:
15 |
16 | 0. [Panduan menulis kode javascript milik Google](https://google.github.io/styleguide/javascriptguide.xml)
17 | 0. [Panduan menulis kode javascript milik Mozilla](https://developer.mozilla.org/en-US/docs/Developer_Guide/Coding_Style)
18 | 0. [Panduan menulis kode javascript milik Douglas](http://javascript.crockford.com/code.html)
19 | 0. [Panduan menulis kode javascript milik Airbnb](https://github.com/airbnb/javascript)
20 |
21 | Tapi setidaknya kami merekomendasikan anda untuk mengikuti [Panduan menulis kode javascript milik Google](https://google.github.io/styleguide/javascriptguide.xml).
22 |
23 | Di halaman GitHub milik AngularJS ada sebuah wiki yang bagus seputar topik ini, kontribusi dari [ProLoser](https://github.com/ProLoser), anda bisa melihatnya di [sini](https://github.com/angular/angular.js/wiki).
24 |
25 | # Daftar isi
26 | * [Umum](#umum)
27 | * [Struktur Direktori](#struktur-direktori)
28 | * [Markup](#markup)
29 | * [Optimasi "digest cycle"](#optimasi-digest-cycle)
30 | * [Lain Lain](#lain-lain)
31 | * [Modules](#modules)
32 | * [Controllers](#controllers)
33 | * [Directives](#directives)
34 | * [Filters](#filters)
35 | * [Services](#services)
36 | * [Templates](#templates)
37 | * [Routing](#routing)
38 | * [Testing](#testing)
39 | * [Kontribusi](#kontribusi)
40 | * [Kontributor](#kontributor)
41 |
42 | # Umum
43 |
44 | ## Struktur Direktori
45 |
46 | Karena sebuah aplikasi bisa mempunyai banyak komponen, sangat baik untuk membuatnya terstruktur seperti struktur direktori.
47 | Ada 2 struktur yang biasa digunakan:
48 |
49 | **Struktur 1:** Membagi menjadi 2 divisi, divisi atas disusun berdasarkan komponen, divisi bawah berdasarkan fungsionalitas.
50 |
51 | Dengan cara ini, struktur akan terlihat seperti ini:
52 |
53 | ```
54 | .
55 | ├── app
56 | │ ├── app.js
57 | │ ├── controllers
58 | │ │ ├── home
59 | │ │ │ ├── FirstCtrl.js
60 | │ │ │ └── SecondCtrl.js
61 | │ │ └── about
62 | │ │ └── ThirdCtrl.js
63 | │ ├── directives
64 | │ │ ├── home
65 | │ │ │ └── directive1.js
66 | │ │ └── about
67 | │ │ ├── directive2.js
68 | │ │ └── directive3.js
69 | │ ├── filters
70 | │ │ ├── home
71 | │ │ └── about
72 | │ └── services
73 | │ ├── CommonService.js
74 | │ ├── cache
75 | │ │ ├── Cache1.js
76 | │ │ └── Cache2.js
77 | │ └── models
78 | │ ├── Model1.js
79 | │ └── Model2.js
80 | ├── partials
81 | ├── lib
82 | └── test
83 | ```
84 |
85 | **Struktur 2:** Membagi menjadi 2 divisi, divisi atas disusun berdasarkan fungsionalitas, divisi bawah berdasarkan komponen.
86 |
87 | Dengan cara ini, struktur akan terlihat seperti ini:
88 |
89 | ```
90 | .
91 | ├── app
92 | │ ├── app.js
93 | │ ├── common
94 | │ │ ├── controllers
95 | │ │ ├── directives
96 | │ │ ├── filters
97 | │ │ └── services
98 | │ ├── home
99 | │ │ ├── controllers
100 | │ │ │ ├── FirstCtrl.js
101 | │ │ │ └── SecondCtrl.js
102 | │ │ ├── directives
103 | │ │ │ └── directive1.js
104 | │ │ ├── filters
105 | │ │ │ ├── filter1.js
106 | │ │ │ └── filter2.js
107 | │ │ └── services
108 | │ │ ├── service1.js
109 | │ │ └── service2.js
110 | │ └── about
111 | │ ├── controllers
112 | │ │ └── ThirdCtrl.js
113 | │ ├── directives
114 | │ │ ├── directive2.js
115 | │ │ └── directive3.js
116 | │ ├── filters
117 | │ │ └── filter3.js
118 | │ └── services
119 | │ └── service3.js
120 | ├── partials
121 | ├── lib
122 | └── test
123 | ```
124 |
125 | **Struktur tambahan:** Ketika membuat directives, akan sangat memudahkan apabila anda menempatkan semua file yang berhubungan (seperti: templates, CSS/SASS) di dalam direktori yang sama. Jika anda mengikuti cara ini, anda harus konsisten.
126 |
127 | ```
128 | app
129 | └── directives
130 | ├── directive1
131 | │ ├── directive1.html
132 | │ ├── directive1.js
133 | │ └── directive1.sass
134 | └── directive2
135 | ├── directive2.html
136 | ├── directive2.js
137 | └── directive2.sass
138 | ```
139 |
140 | Struktur tambahan ini bisa dikombinasikan dengan 2 struktur di atas.
141 |
142 | **Variasi Struktur:** Seperti yang digunakan di proyek [ng-boilerplate](http://joshdmiller.github.io/ng-boilerplate/#/home). Di dalam proyek tersebut, setiap unit testing ditempatkan dalam 1 direktori yang sama dengan komponen. Dengan cara tersebut, anda akan menemukannya dengan cepat dan juga bisa digunakan untuk dokumentasi dan cara penggunaan komponen tersebut.
143 |
144 | ```
145 | services
146 | ├── cache
147 | │ ├── cache1.js
148 | │ └── cache1.spec.js
149 | └── models
150 | ├── model1.js
151 | └── model1.spec.js
152 | ```
153 |
154 | * File `app.js` berisi definisi routing dan konfigurasi.
155 | * Setiap file javascript, hanya boleh berisi sebuah komponen. File tersebut harus diberi nama sesuai nama komponen.
156 | * Alternatif lain, gunakan struktur seperti di [Yeoman](http://yeoman.io), [ng-boilerplate](http://joshdmiller.github.io/ng-boilerplate/#/home).
157 |
158 | Saya sendiri lebih menyukai struktur pertama, karena komponen lebih mudah dicari.
159 |
160 | Untuk Aturan standar penamaan komponen bisa ditemukan di panduan tiap bagian.
161 |
162 | ## Markup
163 |
164 | [TLDR;](http://developer.yahoo.com/blogs/ydn/high-performance-sites-rule-6-move-scripts-bottom-7200.html) Letakan semua script di bagian bawah halaman.
165 |
166 | ```
167 |
168 |
169 |
170 |
171 | MyApp
172 |
173 |
174 |
177 |
178 |
179 |
180 |
181 | ```
182 |
183 | Buat semuanya simpel dan susun file dari yang sangat umum hingga directive yang spesifik di bagian akhir. Dengan begitu lebih mudah untuk melihat, mencari dan mengubahnya.
184 |
185 | ```
186 |
191 | ```
192 |
193 | Untuk atribut HTML yang lain, ikuti panduan [ini](http://mdo.github.io/code-guide/#html-attribute-order)
194 |
195 | ## Optimasi "digest cycle"
196 |
197 | * Hanya 'watch' variabel vital (seperti: ketika menggunakan komunikasi real-time, jangan gunakan `$digest` loop disetiap pesan yang diterima).
198 | * Untuk konten yang diinisialisasi sekali dan tidak pernah berubah lagi, gunakan 'single-time watchers' seperti [`bindonce`](https://github.com/Pasvaz/bindonce).
199 | * Buat komputasi di dalam `$watch` se-simpel mungkin. Karena komputasi berat atau lambat di sebuah `$watch` akan memperlambat seluruh aplikasimu.
200 | * Set false parameter ke 3 di `$timeout` untuk melewatkan `$digest` loop ketika tidak ada lagi variabel yang harus di 'watch'.
201 |
202 | ## Lain Lain
203 |
204 | * Gunakan:
205 | * `$timeout` daripada `setTimeout`
206 | * `$interval` daripada `setInterval`
207 | * `$window` daripada `window`
208 | * `$document` daripada `document`
209 | * `$http` daripada `$.ajax`
210 |
211 | Ini akan mempermudah testing dan akan mencegah kejadian tidak terduga (seperti, jika anda melewatkan `$scope.$apply` di `setTimeout`).
212 |
213 | * Otomatiskan sistem kerja anda dengan tool bantuan seperti:
214 | * [Yeoman](http://yeoman.io)
215 | * [Grunt](http://gruntjs.com)
216 | * [Bower](http://bower.io)
217 |
218 | * Gunakan promises (`$q`) daripada callbacks. Ini akan membuat kode anda lebih elegan dan bersih, dan menyelamatkan anda dari 'callback hell'.
219 | * Gunakan `$resource` daripada `$http` jika memungkinkan. Semakin tinggi level abstraksi, akan menyelamatkan anda dari redudansi.
220 | * Gunakan AngularJS pre-minifier (seperti [ngmin](https://github.com/btford/ngmin) atau [ng-annotate](https://github.com/olov/ng-annotate)) untuk mencegah masalah setelah proses minifikasi.
221 | * Jangan gunakan variabel global. Selalu gunakan Dependency Injection.
222 | * Jangan kotori `$scope`. Hanya tambahkan fungsi dan variabel yang benar-benar akan digunakan.
223 | * Lebih baik inisialisasi variabel di [controllers daripada menggunakan `ngInit`](https://github.com/angular/angular.js/pull/4366/files). Hanya gunakan `ngInit` untuk aliasing di `ngRepeat`.
224 | * Jangan gunakan awalan `$` untuk nama variabel, properti dan fungsi. Awalan ini digunakan oleh AngularJS.
225 | * Ketika melakukan Depedency Injection, susun semuanya dimulai dari library AngularJS terlebih dahulu, setelah itu library kustom anda:
226 |
227 | ```javascript
228 | module.factory('Service', function ($rootScope, $timeout, MyCustomDependency1, MyCustomDependency2) {
229 | return {
230 | //Something
231 | };
232 | });
233 | ```
234 |
235 | # Modules
236 |
237 | * Modules harus diberi nama dengan standar 'lowerCamelCase'. Apabila module `b` adalah submodule dari module `a`, maka anda bisa menumpuknya dengan namespace seperti: `a.b`.
238 |
239 | Ada 2 struktur umum untuk modul:
240 |
241 | 0. Dari fungsionalitas
242 | 0. Dari tipe komponen
243 |
244 | Saat ini 2 struktur di atas tidak terlalu berbeda, tapi yang pertama lebih terlihat bersih. Namun, apabila module 'lazy-loading' sudah diimplementasikan (walaupun saat ini module tersebut tidak ada dalam roadmap tim AngularJS), struktur pertama dapat menambah performa aplikasi anda.
245 |
246 | # Controllers
247 |
248 | * Jangan memanipulasi DOM dari controller, akan membuat controller anda sulit di tes dan melawan prinsip [Separation of Concerns](https://en.wikipedia.org/wiki/Separation_of_concerns). Lebih baik gunakan directive.
249 | * Untuk penamaan controller gunakan standar 'UpperCamelCase' dan harus sesuai dengan fungsionalitasnya (seperti: shopping cart, homepage, admin panel) dan diakhiri dengan `Ctrl` (`HomePageCtrl`, `ShoppingCartCtrl`, `AdminPanelCtrl`, dll.).
250 | * Controller tidak boleh didefinisikan secara global (meskipun AngularJS mengijinkan hal ini, namun sangatlah tidak baik mengotori namespace global).
251 | * Gunakan syntax array untuk definisi controller:
252 |
253 |
254 | ```JavaScript
255 | module.controller('MyCtrl', ['dependency1', 'dependency2', ..., 'dependencyN', function (dependency1, dependency2, ..., dependencyN) {
256 | //...body
257 | }]);
258 | ```
259 |
260 |
261 | Gunakan cara definisi seperti ini untuk menghindarkan masalah minifikasi. Anda dapat secara otomatis menghasilkan definisi seperti di atas dengan menggunakan tool seperti [ng-annotate](https://github.com/olov/ng-annotate) (dan grunt task [grunt-ng-annotate](https://github.com/mzgol/grunt-ng-annotate)).
262 | * Gunakan nama asli dari Dependency Injection, ini akan memudahkanmu membaca kode:
263 |
264 | ```JavaScript
265 | module.controller('MyCtrl', ['$scope', function (s) {
266 | //...body
267 | }]);
268 | ```
269 |
270 | Akan lebih susah dimengerti daripada:
271 |
272 | ```JavaScript
273 | module.controller('MyCtrl', ['$scope', function ($scope) {
274 | //...body
275 | }]);
276 | ```
277 |
278 | Hal ini akan sangat berguna ketika file yang anda baca cukup panjang.
279 |
280 | * Buat controller sesimpel mungkin dan abstraksikan semua logika bisnis ke dalam service.
281 | * Komunikasi dengan controller yang berbeda menggunakan method invocation (memungkinkan ketika child controller ingin berkomunikasi dengan parent controller) atau `$emit`, `$broadcast` dan `$on`. Pesan yang disebarkan harus seminimum mungkin.
282 | * Buatlah daftar semua pesan yang digunakan `$emit`, `$broadcast` dan atur secara hati-hati untuk menghindari nama yang sama.
283 | * Ketika anda ingin mengubah format tampilan data, gunakan [filter](#filters):
284 |
285 | ```JavaScript
286 | module.filter('myFormat', function () {
287 | return function () {
288 | //body...
289 | };
290 | });
291 |
292 | module.controller('MyCtrl', ['$scope', 'myFormatFilter', function ($scope, myFormatFilter) {
293 | //body...
294 | }]);
295 | ```
296 | * Untuk controller yang bertumpuk, gunakan "nested scoping" dengan `controllerAs`:
297 |
298 | **app.js**
299 | ```javascript
300 | module.config(function ($routeProvider) {
301 | $routeProvider
302 | .when('/route', {
303 | templateUrl: 'partials/template.html',
304 | controller: 'HomeCtrl',
305 | controllerAs: 'home'
306 | });
307 | });
308 | ```
309 | **HomeCtrl**
310 | ```javascript
311 | function HomeCtrl() {
312 | this.bindingValue = 42;
313 | }
314 | ```
315 | **template.html**
316 | ```
317 |
318 | ```
319 |
320 | # Directives
321 |
322 | * Gunakan standar penamaan 'lowerCamelCase'.
323 | * Gunakan `scope` daripada `$scope` di dalam link function. Pada saat proses kompilasi, post/pre link function yang telah didefinisikan dengan argumen, akan diberikan ketika fungsi tersebut dipanggil, anda tidak akan dapat mengubahnya dengan Dependency Injection. Cara ini juga digunakan di kode sumber AngularJS.
324 | * Gunakan awalan yang berbeda untuk directive, untuk mencegah error karena penggunaan nama yang sama dengan third-party library.
325 | * Jangan gunakan awalan `ng` atau `ui` karena telah digunakan untuk AngularJS dan AngularJS UI.
326 | * Manipulasi DOM hanya dilakukan di dalam directive.
327 | * Usahakan scope harus terisolasi ketika membuat komponen yang bisa digunakan kembali.
328 | * Gunakan directive di atribut atau elemen daripada di komentar atau class, ini akan membuat kode lebih mudah dibaca.
329 | * Gunakan `$scope.$on('$destroy', fn)` untuk membersihkan. Sangat berguna terutama ketika anda menggunakan third-party plugin sebagai directive.
330 | * Jangan lupa gunakan `$sce` untuk konten yang tidak dapat dipercaya.
331 |
332 | # Filters
333 |
334 | * Gunakan standar penamaan 'lowerCamelCase'.
335 | * Buat filter anda se-ringan mungkin karena sering dipanggil selama `$digest` loop.
336 | * Fokus lakukan 1 hal saja untuk setiap filter. Untuk manipulasi lebih kompleks, lebih baik menggabungkan beberapa filter sekaligus.
337 |
338 | # Services
339 |
340 | Bagian ini adalah informasi tentang komponen service secara umum di AngularJS dan tidak spesifik tentang (`provider`, `.factory` atau `.service`), kecuali ditegaskan demikian.
341 |
342 | * Gunakan standar penamaan 'camelCase'.
343 | * UpperCamelCase (PascalCase) untuk nama service apabila digunakan sebagai konstruktor, seperti:
344 |
345 | ```JavaScript
346 | module.controller('MainCtrl', function ($scope, User) {
347 | $scope.user = new User('foo', 42);
348 | });
349 |
350 | module.factory('User', function () {
351 | return function User(name, age) {
352 | this.name = name;
353 | this.age = age;
354 | };
355 | });
356 | ```
357 |
358 | * lowerCamelCase untuk semua service yang lain.
359 |
360 | * Enkapsulasikan semua logika bisnis di dalam service.
361 | * Service yang merepresentasikan domain lebih baik adalah `service` daripada `factory`. Dengan begitu kita dapat lebih mudah mendapatkan keuntungan dari "klassical" inheritance:
362 |
363 | ```JavaScript
364 | function Human() {
365 | //body
366 | }
367 | Human.prototype.talk = function () {
368 | return "I'm talking";
369 | };
370 |
371 | function Developer() {
372 | //body
373 | }
374 | Developer.prototype = Object.create(Human.prototype);
375 | Developer.prototype.code = function () {
376 | return "I'm coding";
377 | };
378 |
379 | myModule.service('Human', Human);
380 | myModule.service('Developer', Developer);
381 |
382 | ```
383 |
384 | * Untuk cache pada level session gunakan `$cacheFactory`. Ini harus digunakan untuk meng-cache hasil dari request atau komputasi yang berat.
385 | * Jika sebuah service membutuhkan konfigurasi, maka definisikan service tersebut sebagai provider dan konfigurasikan service itu di dalam `config` callback seperti:
386 |
387 | ```JavaScript
388 | angular.module('demo', [])
389 | .config(function ($provide) {
390 | $provide.provider('sample', function () {
391 | var foo = 42;
392 | return {
393 | setFoo: function (f) {
394 | foo = f;
395 | },
396 | $get: function () {
397 | return {
398 | foo: foo
399 | };
400 | }
401 | };
402 | });
403 | });
404 |
405 | var demo = angular.module('demo');
406 |
407 | demo.config(function (sampleProvider) {
408 | sampleProvider.setFoo(41);
409 | });
410 | ```
411 |
412 | # Templates
413 |
414 | * Gunakan `ng-bind` atau `ng-cloak` daripada `{{ }}` untuk mencegah konten yang berkedip (flashing content).
415 | * Hindari menulis ekspresi yang kompleks di dalam template.
416 | * Gunakan `ng-src` dan `{{ }}` daripada hanya `src`
417 | * Gunakan `ng-href` daripada `src` dan `{{ }}`
418 | * Gunakan `ng-style` daripada `style` dan `{{ }}`
419 |
420 | ```HTML
421 |
429 |
430 | my beautifully styled div which will work in IE
;
431 | ```
432 |
433 | # Routing
434 |
435 | * Gunakan `resolve` untuk resolve dependencies sebelum view ditampilkan.
436 |
437 | # Testing
438 |
439 | TBD
440 |
441 | Sampai bagian ini selesai, anda bisa menggunakan panduan [ini](https://github.com/daniellmb/angular-test-patterns) terlebih dahulu.
442 |
443 | # Kontribusi
444 |
445 | Karena panduan ini dibuat oleh komunitas, kontribusi sangatlah dihargai.
446 | Contohnya, anda dapat berkontribusi dengan memperluas bagian testing atau dengan menerjemahkan panduan ini ke dalam bahasa anda.
447 |
448 | # Kontributor
449 |
450 | [](https://github.com/mgechev) |[](https://github.com/pascalockert) |[](https://github.com/mainyaa) |[](https://github.com/rubystream) |[](https://github.com/lukaszklis) |
451 | :---: |:---: |:---: |:---: |:---: |
452 | [mgechev](https://github.com/mgechev) |[pascalockert](https://github.com/pascalockert) |[mainyaa](https://github.com/mainyaa) |[rubystream](https://github.com/rubystream) |[lukaszklis](https://github.com/lukaszklis) |
453 |
454 | [](https://github.com/cironunes) |[](https://github.com/cavarzan) |[](https://github.com/tornad) |[](https://github.com/jmblog) |[](https://github.com/bargaorobalo) |
455 | :---: |:---: |:---: |:---: |:---: |
456 | [cironunes](https://github.com/cironunes) |[cavarzan](https://github.com/cavarzan) |[tornad](https://github.com/tornad) |[jmblog](https://github.com/jmblog) |[bargaorobalo](https://github.com/bargaorobalo) |
457 |
458 | [](https://github.com/astalker) |[](https://github.com/valgreens) |[](https://github.com/bitdeli-chef) |[](https://github.com/dchest) |[](https://github.com/gsamokovarov) |
459 | :---: |:---: |:---: |:---: |:---: |
460 | [astalker](https://github.com/astalker) |[valgreens](https://github.com/valgreens) |[bitdeli-chef](https://github.com/bitdeli-chef) |[dchest](https://github.com/dchest) |[gsamokovarov](https://github.com/gsamokovarov) |
461 |
462 | [](https://github.com/ntaoo) |[](https://github.com/hermankan) |[](https://github.com/jesselpalmer) |[](https://github.com/capaj) |[](https://github.com/jordanyee) |
463 | :---: |:---: |:---: |:---: |:---: |
464 | [ntaoo](https://github.com/ntaoo) |[hermankan](https://github.com/hermankan) |[jesselpalmer](https://github.com/jesselpalmer) |[capaj](https://github.com/capaj) |[jordanyee](https://github.com/jordanyee) |
465 |
466 | [](https://github.com/nacyot) |[](https://github.com/kirstein) |[](https://github.com/mo-gr) |[](https://github.com/cryptojuice) |[](https://github.com/olov) |
467 | :---: |:---: |:---: |:---: |:---: |
468 | [nacyot](https://github.com/nacyot) |[kirstein](https://github.com/kirstein) |[mo-gr](https://github.com/mo-gr) |[cryptojuice](https://github.com/cryptojuice) |[olov](https://github.com/olov) |
469 |
470 | [](https://github.com/vorktanamobay) |[](https://github.com/thomastuts) |[](https://github.com/grapswiz) |[](https://github.com/coderhaoxin) |[](https://github.com/dreame4) |
471 | :---: |:---: |:---: |:---: |:---: |
472 | [vorktanamobay](https://github.com/vorktanamobay) |[thomastuts](https://github.com/thomastuts) |[grapswiz](https://github.com/grapswiz) |[coderhaoxin](https://github.com/coderhaoxin) |[dreame4](https://github.com/dreame4) |
473 |
474 | [](https://github.com/guiltry) |
475 | :---: |
476 | [guiltry](https://github.com/guiltry) |
477 |
--------------------------------------------------------------------------------
/README-it-it.md:
--------------------------------------------------------------------------------
1 | # Introduzione
2 |
3 | Questo documento è finalizzato al presentare una serie di buone pratiche e
4 | linee guida per lo stile e l'applicazione di AngularJS.
5 | Queste pratiche derivano da:
6 |
7 | 0. Codice AngularJS
8 | 0. Codice e articoli che ho letto
9 | 0. Esperienza
10 |
11 | **Nota 1**: Questo è ancora un abbozzo della guida stilistica: il suo obiettivo
12 | è di essere guidato dalla community, quindi eventuali migliorie sarebbero
13 | molto apprezzate da parte di tutti.
14 |
15 | In questa guida non si accennerà a comuni linee guida sulla programmazione
16 | JavaScript. Queste possono essere trovate nei seguenti link:
17 |
18 | 0. [Google's JavaScript style guide](https://google.github.io/styleguide/javascriptguide.xml)
19 | 0. [Mozilla's JavaScript style guide](https://developer.mozilla.org/en-US/docs/Developer_Guide/Coding_Style)
20 | 0. [Douglas Crockford's JavaScript style guide](http://javascript.crockford.com/code.html)
21 | 0. [Airbnb JavaScript style guide](https://github.com/airbnb/javascript)
22 |
23 | Per la programmazione AngularJS è raccomandato: [Google's JavaScript style guide](https://google.github.io/styleguide/javascriptguide.xml).
24 |
25 | Nel repository AngularJS su GitHub c'è una sezione simile curata da [ProLoser](https://github.com/ProLoser). Potete visionarla [quì](https://github.com/angular/angular.js/wiki).
26 |
27 | # Contenuti
28 | * [Generale](#generale)
29 | * [Struttura delle directory](#struttura-delle-directory)
30 | * [Markup](#markup)
31 | * [Ottimizzare il ciclo digest](#ottimizzare-il-ciclo-digest)
32 | * [Altro](#altro)
33 | * [Module](#module)
34 | * [Controller](#controller)
35 | * [Directive](#directive)
36 | * [Filter](#filter)
37 | * [Service](#service)
38 | * [Template](#template)
39 | * [Routing](#routing)
40 | * [Testing](#testing)
41 | * [Collaborazioni](#collaborazioni)
42 | * [Collaboratori](#collaboratori)
43 |
44 | # Generale
45 |
46 | ## Struttura delle directory
47 |
48 | Dal momento che una grande applicazione di AngularJS implica tante componenti,
49 | sarebbe consigliabile strutturare i file e le directory in maniera gerarchica.
50 | Ci sono due possibili approcci:
51 |
52 | * Creare una divisione ad alto livello in base al tipo di componenti ed una a
53 | basso livello in base alle funzionalità
54 |
55 | In questo modo le directory avranno questa struttura:
56 |
57 | ```
58 | .
59 | ├── app
60 | │ ├── app.js
61 | │ ├── controllers
62 | │ │ ├── home
63 | │ │ │ ├── FirstCtrl.js
64 | │ │ │ └── SecondCtrl.js
65 | │ │ └── about
66 | │ │ └── ThirdCtrl.js
67 | │ ├── directives
68 | │ │ ├── home
69 | │ │ │ └── directive1.js
70 | │ │ └── about
71 | │ │ ├── directive2.js
72 | │ │ └── directive3.js
73 | │ ├── filters
74 | │ │ ├── home
75 | │ │ └── about
76 | │ └── services
77 | │ ├── CommonService.js
78 | │ ├── cache
79 | │ │ ├── Cache1.js
80 | │ │ └── Cache2.js
81 | │ └── models
82 | │ ├── Model1.js
83 | │ └── Model2.js
84 | ├── partials
85 | ├── lib
86 | └── test
87 | ```
88 |
89 | * Creare una divisione ad alto livello in base alle funzionalità ed una a basso
90 | livello in base al tipo di componenti
91 |
92 | Questa divisione avrà invece questo tipo di struttura:
93 |
94 | ```
95 | .
96 | ├── app
97 | │ ├── app.js
98 | │ ├── common
99 | │ │ ├── controllers
100 | │ │ ├── directives
101 | │ │ ├── filters
102 | │ │ └── services
103 | │ ├── home
104 | │ │ ├── controllers
105 | │ │ │ ├── FirstCtrl.js
106 | │ │ │ └── SecondCtrl.js
107 | │ │ ├── directives
108 | │ │ │ └── directive1.js
109 | │ │ ├── filters
110 | │ │ │ ├── filter1.js
111 | │ │ │ └── filter2.js
112 | │ │ └── services
113 | │ │ ├── service1.js
114 | │ │ └── service2.js
115 | │ └── about
116 | │ ├── controllers
117 | │ │ └── ThirdCtrl.js
118 | │ ├── directives
119 | │ │ ├── directive2.js
120 | │ │ └── directive3.js
121 | │ ├── filters
122 | │ │ └── filter3.js
123 | │ └── services
124 | │ └── service3.js
125 | ├── partials
126 | ├── lib
127 | └── test
128 | ```
129 |
130 | * Quando si creano le directive sarebbe utile mettere tutti i file associati
131 | ad una data directive (es: template, CSS/SASS file,
132 | JavaScript) in una singola cartella. Se scegliete di usare questo stile, siate
133 | coerenti e usatelo in ogni occasione.
134 |
135 | ```
136 | app
137 | └── directives
138 | ├── directive1
139 | │ ├── directive1.html
140 | │ ├── directive1.js
141 | │ └── directive1.sass
142 | └── directive2
143 | ├── directive2.html
144 | ├── directive2.js
145 | └── directive2.sass
146 | ```
147 |
148 | Questo approccio può essere combinato con entrambe le strutture di directory
149 | trattate in precedenza
150 | * Un'ulteriore leggera variazione di entrambe le strutture è quella usata in
151 | [ng-boilerplate](http://joshdmiller.github.io/ng-boilerplate/#/home). In
152 | questa, le unit tests per un determinato componente sono poste nella stessa
153 | cartella del componente stesso. In questo modo quando vengono fatti cambiamenti
154 | ad un componente è più semplice trovare il relativo test. Il test, in questo
155 | modo, fa anche da documentazione e mostra i casi d'uso.
156 |
157 | ```
158 | services
159 | ├── cache
160 | │ ├── cache1.js
161 | │ └── cache1.spec.js
162 | └── models
163 | ├── model1.js
164 | └── model1.spec.js
165 | ```
166 |
167 | * Il file `app-js` contiene la definizione dei route, impostazioni e/o
168 | bootstrap manuali (se richiesti).
169 | * Ogni file JavaScript dovrebbe contenere solo un singolo componente. Il file
170 | dovrebbe essere chiamato con il nome del componente.
171 | * Per il progetto AngularJS, usate una struttura di template simile alla
172 | seguente:
173 | * The `app.js` file contains route definitions, configuration and/or manual bootstrap (if required). [ng-boilerplate](http://joshdmiller.github.io/ng-boilerplate/#/home).
174 |
175 | Personalmente preferisco la prima struttura perché rende più facili da trovare
176 | i componenti più comuni.
177 |
178 | Convenzioni su come chiamare i componenti possono essere trovate nelle sezioni
179 | relative agli stessi.
180 |
181 | ## Markup
182 |
183 | [TLDR;](http://developer.yahoo.com/blogs/ydn/high-performance-sites-rule-6-move-scripts-bottom-7200.html) Metti lo script in basso.
184 |
185 | ```
186 |
187 |
188 |
189 |
190 | MyApp
191 |
192 |
193 |
196 |
197 |
198 |
199 |
200 | ```
201 |
202 | Mantieni il codice semplice e metti le direttive AngularJS in fondo. In questo
203 | modo è più semplice la lettura e la mantenibilità del codice HTML.
204 |
205 | ```
206 |
211 | ```
212 |
213 | Gli altri attrubuti HTML dovrebbero seguire la seguente [guida](http://mdo.github.io/code-guide/#html-attribute-order)
214 |
215 | ## Ottimizzare il ciclo digest
216 |
217 | * Eseguire un watch solo per le variabili più importanti (es: usando un tipo di
218 | comunicazione real-time, non permettere un ciclo `$digest` per ogni messaggio
219 | ricevuto).
220 | * Per contenuti che sono inizializzati solo una volta e mai cambiati, usare un
221 | single-time watcher come [`bindonce`](https://github.com/Pasvaz/bindonce).
222 | * Rendere le computazioni in `$watch` il più semplici possibile. Rendendo
223 | pesanti e lenti i calcoli in un singolo `$watch`, si abbasseranno le
224 | prestazioni dell'intera applicazione (il ciclo `$digest` è eseguito in un
225 | singolo thread a causa della natura single-threaded di JavaScript).
226 | * Settare il ternzo parametro nella funzione `$timeout` a false, per evitare
227 | un ulteriore ciclo `$digest` quando variabili non necessarie sono implicate
228 | nella funzione callback di `$timeout`.
229 |
230 | ## Altro
231 |
232 | * Usare:
233 | * `$timeout` invece di `setTimeout`
234 | * `$interval` invece di `setInterval`
235 | * `$window` invece di `window`
236 | * `$document` invece di `document`
237 | * `$http` invece di `$.ajax`
238 |
239 | Questo renderà il testing più semplice e, in alcuni casi, impedirà
240 | comportamenti inaspettati (come il dimenticarsi `$scope.$apply` in
241 | `setTimeout`).
242 |
243 | * Automatizzare il lavoro usando utility come:
244 | * [Yeoman](http://yeoman.io)
245 | * [Grunt](http://gruntjs.com)
246 | * [Bower](http://bower.io)
247 |
248 | * Usare promise (`$q`) invece dei callback. Questo renderà il codice più
249 | elegante e pulito, oltre che salvarvi dall'inferno dei callback.
250 | * Usare `$resource` invece di `$http`. Il più alto livello d'astrazione vi
251 | salverà dalle ridondanze.
252 | * Usare un pre-minificatore per AngularJS (ad esempio
253 | [ngmin](https://github.com/btford/ngmin) o
254 | [ng-annotate](https://github.com/olov/ng-annotate)) per evitare problemi dopo
255 | la minificazione.
256 | * Non usare variabili globali. Risolvere tutte le dipendenze usando il
257 | Dipendency Injection.
258 | * Non riempire lo `$scope` se non con variabili e funzioni usate nel template.
259 | * E' da preferire l'utilizzo di
260 | [controller invece di `ngInit`](https://github.com/angular/angular.js/pull/4366/files).
261 | Il solo utilizzo appropriato di `ngInit` è per rinominare particolari proprietà
262 | di `ngRepeat`. A parte quest'ultimo caso, si dovrebbero usare controller per
263 | inizializzare variabili nello scope.
264 | * Non usare il prefisso `$` per i nomi di variabili, proprietà o metodi. Questo
265 | prefisso è riservato ad AngularJS.
266 | * Quando si risolvono dipendenze attraverso il meccanismo DI di AngularJS,
267 | ordinare tutte le dipendenze in base al loro tipo - le dipendenze built-in di
268 | AngularJS dovrebbero essere le prime, seguite da quelle create da voi:
269 |
270 | ```javascript
271 | module.factory('Service', function ($rootScope, $timeout, MyCustomDependency1, MyCustomDependency2) {
272 | return {
273 | //Something
274 | };
275 | });
276 | ```
277 |
278 | # Module
279 |
280 | * Il nome dei module dovrebbe essere assegnato secondo il lowerCamelCase. Per
281 | indicare che un module `b` è submodule di `a` si possono concatenare usando un
282 | namespacing come: `a.b`.
283 |
284 | Ci sono due metodi più comuni per strutturare i modulo:
285 |
286 | 0. In base alla funzionalità
287 | 0. In base al tipo di componente
288 |
289 | Al momento non c'è grande differenza, ma il primo metodo sembra più pulito.
290 | Inoltre, se verrà implementato il lazy-loading modules (il che non è tra i
291 | piani di AngularJS), le prestazioni delle app aumenteranno.
292 |
293 | # Controller
294 |
295 | * Non manipolare il DOM nei controller: questo renderà i controller difficili
296 | da testare e violerà il
297 | [principio di separazione degli interessi](https://en.wikipedia.org/wiki/Separation_of_concerns).
298 | Usare, invece, le directive.
299 | * Il nome dei controller è assegnato in base alla loro funzionalità (ad esempio
300 | shopping cart, homepage, admin panel) più il suffisso 'Ctrl'. I nomi utilizzano
301 | in questo caso l'UpperCamelCase (`HomePageCtrl`, `ShoppingCartCtrl`,
302 | `AdminPanelCtrl`, ecc.).
303 | * I controller non dovrebbero mai essere definiti come globali (anche se
304 | AngularJS lo permette, inquinare il namspace globale è una brutta partica).
305 | * Usare la sintassi ad array per la definizione dei controller:
306 |
307 | ```JavaScript
308 | module.controller('MyCtrl', ['dependency1', 'dependency2', ..., 'dependencyn', function (dependency1, dependency2, ..., dependencyn) {
309 | //...body
310 | }]);
311 | ```
312 |
313 | Usando questo tipo di definizione si evitano problemi con la minificazione.
314 | So possono generare definizioni ad array da quelle standard utilizzando tool
315 | come [ng-annotate](https://github.com/olov/ng-annotate)
316 | o le task di grunt [grunt-ng-annotate](https://github.com/mzgol/grunt-ng-annotate)
317 | Usare il nome originale delle dipendenze dei controller. Questo vi aiuterà nel
318 | produrre un codice più leggibile:
319 |
320 | ```JavaScript
321 | module.controller('MyCtrl', ['$scope', function (s) {
322 | //...body
323 | }]);
324 | ```
325 |
326 | è più leggibile di:
327 |
328 | ```JavaScript
329 | module.controller('MyCtrl', ['$scope', function ($scope) {
330 | //...body
331 | }]);
332 | ```
333 |
334 | Questo principio si applica soprattutto quando i file sono così grandi da aver
335 | bisogno di scrollare la pagina. Questo farebbe dimenticare facilmente al
336 | lettore quale variabile è legata a quale dipendenza.
337 |
338 | * Rendere i controller il più leggeri possibile. Astrarre le funzioni comuni in
339 | service.
340 | * Comunicare all'interno dei controller invocando metodi (possibile quando un
341 | figlio vuole comunicare con il genitore) o con i metodi `$emit`, `$broadcast`
342 | e `$on`. I messaggi emessi e trasmessi dovrebbero ridursi al minimo.
343 | * Creare una lista di tutti i messaggi che sono passati usando `$emit` e
344 | `$broadcast` e manovrarli con attenzione per evitare collisioni di nomi ed bug.
345 | * Quando si ha bisogno di formattare dati, incapsulare la logica di
346 | formattazione in un [filter](#filters) e dichiararlo come dipendenza:
347 |
348 | ```JavaScript
349 | module.filter('myFormat', function () {
350 | return function () {
351 | //body...
352 | };
353 | });
354 |
355 | module.controller('MyCtrl', ['$scope', 'myFormatFilter', function ($scope, myFormatFilter) {
356 | //body...
357 | }]);
358 | ```
359 | * In caso di controller annidati, usare "nested scoping" (la sintassi
360 | `controllerAs`):
361 |
362 | **app.js**
363 | ```javascript
364 | module.config(function ($routeProvider) {
365 | $routeProvider
366 | .when('/route', {
367 | templateUrl: 'partials/template.html',
368 | controller: 'HomeCtrl',
369 | controllerAs: 'home'
370 | });
371 | });
372 | ```
373 | **HomeCtrl**
374 | ```javascript
375 | function HomeCtrl() {
376 | this.bindingValue = 42;
377 | }
378 | ```
379 | **template.html**
380 | ```
381 |
382 | ```
383 |
384 | # Directive
385 |
386 | * Assegnare i nomi alle directive seguendo il lowerCamelCase
387 | * Usare `scope` invece di `$scope` alle funzioni link. Per le funzioni compile
388 | e post/pre link, avrete già definito i parametri che verranno passati quando la
389 | funzione verrà invocata e non vi sarà possibile cambiarli usando il DI. Questo
390 | stile è utilizzato anche nel codice di AngularJS
391 | * Usare prefissi personalizzati per le direttive per evitare collisioni con
392 | librerie di terze parti.
393 | * Non usare i prefissi `ng` e `ui`, poichè sono già utilizzati da AngularJS e
394 | AngularJS UI.
395 | * La manipolazione del DOM deve essere effettuata solo attraverso le directive.
396 | * Creare scope isolati quando si creano directiv riusabili.
397 | * Usare direttive come attributi o elementi invece di commenti o classi: questo
398 | renderà il codice più leggibile.
399 | * Usare `$scope.$on('$destroy', fn)` per pulire. Questo è molto utile
400 | specialmente quando si fa il wrapping di plugin e directive di terze parti.
401 | * Non dimenticare di usare `$sce` quando si ha a che fare con contenuti non
402 | affidabili
403 |
404 | # Filter
405 |
406 | * Assegnare i nomi ai filter seguendo il lowerCamelCase.
407 | * I filter dovrebbero essere più leggeri possibile. Vengono spesso invocati
408 | durante il ciclo `$digest`, quindi un filtro poco performante potrebbe incidere
409 | sulle performance della vostra applicazione.
410 | * Usare ogni filter per un solo scopo mantenendoli coerenti. Manipolazioni più
411 | complesse possono essere ottenute concatenando più filter.
412 |
413 | # Service
414 |
415 | Questa sezione include informazioni sui componenti service di AngularJS. Questi
416 | non dipendono dal tipo di definizione (es: come provider, `.factory`,
417 | `.service`) a meno che questo non è esplicitamente menzionato.
418 |
419 | * Usare camelCase per assegnare nomi ai service:
420 | * UpperCamelCase (PascalCase) per service usati come costruttori. Es:
421 |
422 | ```JavaScript
423 | module.controller('MainCtrl', function ($scope, User) {
424 | $scope.user = new User('foo', 42);
425 | });
426 |
427 | module.factory('User', function () {
428 | return function User(name, age) {
429 | this.name = name;
430 | this.age = age;
431 | };
432 | });
433 | ```
434 |
435 | * lowerCamelCase per gli altri casi.
436 |
437 | * Incapsulare tutte le logiche di business in service.
438 | * Service che rappresentano domini dovrebbero essere definiti come `service`
439 | piuttosto che `factory`. In questo modo ci si può avvantagiare dell'
440 | ereditarietà "klassical" in modo più semplice:
441 |
442 | ```JavaScript
443 | function Human() {
444 | //body
445 | }
446 | Human.prototype.talk = function () {
447 | return "I'm talking";
448 | };
449 |
450 | function Developer() {
451 | //body
452 | }
453 | Developer.prototype = Object.create(Human.prototype);
454 | Developer.prototype.code = function () {
455 | return "I'm coding";
456 | };
457 |
458 | myModule.service('Human', Human);
459 | myModule.service('Developer', Developer);
460 |
461 | ```
462 |
463 | * Per cache di session-level si può usare `$cacheFactory`. Questo dovrebbe
464 | essere usato come risultato cache di richieste o pesanti calcoli.
465 | * Se un dato service richiede una configurazione, definirlo come provider e
466 | configurarlo nel callback di `config`:
467 |
468 | ```JavaScript
469 | angular.module('demo', [])
470 | .config(function ($provide) {
471 | $provide.provider('sample', function () {
472 | var foo = 42;
473 | return {
474 | setFoo: function (f) {
475 | foo = f;
476 | },
477 | $get: function () {
478 | return {
479 | foo: foo
480 | };
481 | }
482 | };
483 | });
484 | });
485 |
486 | var demo = angular.module('demo');
487 |
488 | demo.config(function (sampleProvider) {
489 | sampleProvider.setFoo(41);
490 | });
491 | ```
492 |
493 | # Template
494 |
495 | * Usare `ng-bind` o `ng-cloak` invece di `{{ }}` per evitare il flashing
496 | content.
497 | * Evitare di scrivere espressioni complesse nei template.
498 | * Quando si ha bisogno di settare `src` ad un'immagine in modo dimamico, usare
499 | `ng-src` invece di `src` con `{{ }}`.
500 | * Quando si ha bisogno di settare `href` ad un tag dimaicamente, usare
501 | `ng-href` invece di `href` con `{{ }}`.
502 | * Invece di usare variabili di scope come stringa e usarli nell'attributo
503 | `style` racchiusi da `{{ }}`, utilizzare la directive `ng-style` con parametri
504 | oggetti e variabili dello scope come valori:
505 |
506 | ```HTML
507 |
515 |
516 | my beautifully styled div which will work in IE
;
517 | ```
518 |
519 | # Routing
520 |
521 | * Usare `resolve` per risolvere le dipendenze prima di mostrare le view.
522 |
523 | # Testing
524 |
525 | In corso di stesura.
526 |
527 | Finchè la sezione non è pronta, si può fare riferimento a
528 | [questo link](https://github.com/daniellmb/angular-test-patterns).
529 |
530 | # Collaborazioni
531 |
532 | Dal momento che l'obiettivo di questa guida stilistica è di essere portata
533 | avanti dalla community, eventuali collaborazioni sono grandemente apprezzate.
534 | Ad esempio, si può contribuire estendendo la sezione di Testing o traducendo la
535 | guida nella propria lingua
536 |
537 | # Collaboratori
538 |
539 | [](https://github.com/mgechev) |[](https://github.com/pascalockert) |[](https://github.com/mainyaa) |[](https://github.com/rubystream) |[](https://github.com/lukaszklis) |
540 | :---: |:---: |:---: |:---: |:---: |
541 | [mgechev](https://github.com/mgechev) |[pascalockert](https://github.com/pascalockert) |[mainyaa](https://github.com/mainyaa) |[rubystream](https://github.com/rubystream) |[lukaszklis](https://github.com/lukaszklis) |
542 |
543 | [](https://github.com/cironunes) |[](https://github.com/cavarzan) |[](https://github.com/tornad) |[](https://github.com/jmblog) |[](https://github.com/bargaorobalo) |
544 | :---: |:---: |:---: |:---: |:---: |
545 | [cironunes](https://github.com/cironunes) |[cavarzan](https://github.com/cavarzan) |[tornad](https://github.com/tornad) |[jmblog](https://github.com/jmblog) |[bargaorobalo](https://github.com/bargaorobalo) |
546 |
547 | [](https://github.com/astalker) |[](https://github.com/valgreens) |[](https://github.com/bitdeli-chef) |[](https://github.com/dchest) |[](https://github.com/gsamokovarov) |
548 | :---: |:---: |:---: |:---: |:---: |
549 | [astalker](https://github.com/astalker) |[valgreens](https://github.com/valgreens) |[bitdeli-chef](https://github.com/bitdeli-chef) |[dchest](https://github.com/dchest) |[gsamokovarov](https://github.com/gsamokovarov) |
550 |
551 | [](https://github.com/ntaoo) |[](https://github.com/hermankan) |[](https://github.com/jesselpalmer) |[](https://github.com/capaj) |[](https://github.com/jordanyee) |
552 | :---: |:---: |:---: |:---: |:---: |
553 | [ntaoo](https://github.com/ntaoo) |[hermankan](https://github.com/hermankan) |[jesselpalmer](https://github.com/jesselpalmer) |[capaj](https://github.com/capaj) |[jordanyee](https://github.com/jordanyee) |
554 |
555 | [](https://github.com/nacyot) |[](https://github.com/kirstein) |[](https://github.com/mo-gr) |[](https://github.com/cryptojuice) |[](https://github.com/olov) |
556 | :---: |:---: |:---: |:---: |:---: |
557 | [nacyot](https://github.com/nacyot) |[kirstein](https://github.com/kirstein) |[mo-gr](https://github.com/mo-gr) |[cryptojuice](https://github.com/cryptojuice) |[olov](https://github.com/olov) |
558 |
559 | [](https://github.com/vorktanamobay) |[](https://github.com/thomastuts) |[](https://github.com/grapswiz) |[](https://github.com/coderhaoxin) |[](https://github.com/dreame4) |
560 | :---: |:---: |:---: |:---: |:---: |
561 | [vorktanamobay](https://github.com/vorktanamobay) |[thomastuts](https://github.com/thomastuts) |[grapswiz](https://github.com/grapswiz) |[coderhaoxin](https://github.com/coderhaoxin) |[dreame4](https://github.com/dreame4) |
562 |
--------------------------------------------------------------------------------
/README-pl-pl.md:
--------------------------------------------------------------------------------
1 | # Wprowadzenie
2 |
3 | Celem tego style guide'a jest przedstawienie zbioru najlepszych praktyk i wytycznych dla aplikacji napisanych w AngularJS. Opisywane praktyki to zbiór:
4 |
5 | 0. Kodu źródłowego AngularJS
6 | 0. Kodu źródłowego lub artykułów, które przeczytałem
7 | 0. Własnego doświadczenia
8 |
9 | **Uwaga**: to wciąż szkic style guide'a, jego przeznaczeniem jest to, aby był tworzony przez społeczność, tak więc uzupełnianie go, będzie docenione przez całą społeczność.
10 |
11 | W tym style guidzie nie znajdziesz wytycznych do programowania w JavaScriptcie. Takowe znajdziesz tu:
12 |
13 | 0. [Style guide'y JavaScriptu Google'a](https://google.github.io/styleguide/javascriptguide.xml)
14 | 0. [Style guide'y JavaScriptu Mozilli](https://developer.mozilla.org/en-US/docs/Developer_Guide/Coding_Style)
15 | 0. [Style guide'y JavaScriptu Douglasa Crockforda](http://javascript.crockford.com/code.html)
16 | 0. [Style guide'y JavaScriptu AirBnB](https://github.com/airbnb/javascript)
17 |
18 | Do pisania kodu w AngularJS, zaleca się stosować do wytycznych przygotowanych przez [Google'a](https://google.github.io/styleguide/javascriptguide.xml).
19 |
20 | Na stronach wiki projektu AngularJS na Githubie, istnieje podobna sekcja przygotowana przez [ProLoser](https://github.com/ProLoser), możesz się z nią zapoznać [tu](https://github.com/angular/angular.js/wiki).
21 |
22 | # Spis treści
23 | * [Ogólne](#ogólne)
24 | * [Struktura katalogów](#struktura-katalogów)
25 | * [Optymalizuj cykl `$digest`](#optymalizuj-cykl-digest)
26 | * [Inne](#inne)
27 | * [Moduły](#moduły)
28 | * [Kontrolery](#kontrolery)
29 | * [Dyrektywy](#dyrektywy)
30 | * [Filtry](#filtry)
31 | * [Usługi](#usługi)
32 | * [Szablony](#szablony)
33 | * [Routing](#routing)
34 | * [Testy](#testy)
35 | * [Wsparcie](#wsparcie)
36 |
37 | # Ogólne
38 |
39 | ## Struktura katalogów
40 |
41 | Duże aplikacje napisane w AngularJS posiadają wiele komponentów, dlatego też najlepiej grupować je w katalogi. Istnieją dwa podejścia:
42 |
43 | * Tworzenie katalogów wysokiego poziomu, w oparciu o podział na typy komponentów oraz niższego poziomu, w oparciu o podział na funkcjonalność.
44 |
45 | W przypadku tego typu podziału, struktura naszego projektu będzie się kształtować następująco:
46 |
47 | .
48 | ├── app
49 | │ ├── app.js
50 | │ ├── controllers
51 | │ │ ├── page1
52 | │ │ │ ├── FirstCtrl.js
53 | │ │ │ └── SecondCtrl.js
54 | │ │ └── page2
55 | │ │ └── ThirdCtrl.js
56 | │ ├── directives
57 | │ │ ├── page1
58 | │ │ │ └── directive1.js
59 | │ │ └── page2
60 | │ │ ├── directive2.js
61 | │ │ └── directive3.js
62 | │ ├── filters
63 | │ │ ├── page1
64 | │ │ └── page2
65 | │ └── services
66 | │ ├── CommonService.js
67 | │ ├── cache
68 | │ │ ├── Cache1.js
69 | │ │ └── Cache2.js
70 | │ └── models
71 | │ ├── Model1.js
72 | │ └── Model2.js
73 | ├── lib
74 | └── test
75 |
76 | * Tworzenie katalogów wysokiego poziomu, w oparciu o podział na funkcjonalność oraz niższego poziomu, w oparciu o podział na typy komponentów.
77 |
78 | Przykład struktury:
79 |
80 | .
81 | ├── app
82 | │ ├── app.js
83 | │ ├── common
84 | │ │ ├── controllers
85 | │ │ ├── directives
86 | │ │ ├── filters
87 | │ │ └── services
88 | │ ├── page1
89 | │ │ ├── controllers
90 | │ │ │ ├── FirstCtrl.js
91 | │ │ │ └── SecondCtrl.js
92 | │ │ ├── directives
93 | │ │ │ └── directive1.js
94 | │ │ ├── filters
95 | │ │ │ ├── filter1.js
96 | │ │ │ └── filter2.js
97 | │ │ └── services
98 | │ │ ├── service1.js
99 | │ │ └── service2.js
100 | │ └── page2
101 | │ ├── controllers
102 | │ │ └── ThirdCtrl.js
103 | │ ├── directives
104 | │ │ ├── directive2.js
105 | │ │ └── directive3.js
106 | │ ├── filters
107 | │ │ └── filter3.js
108 | │ └── services
109 | │ └── service3.js
110 | ├── lib
111 | └── test
112 |
113 | * W przypadku tworzenie dyrektywy, przydatnym jest umieszczenie wszystkich plików powiązanych z tworzoną dyrektywą (np. szablony, pliki CSS/SASS, pliki JS) w jednym folderze. Jeżeli wybierzesz ten styl struktury, bądź konsekwentny w całym projekcie.
114 |
115 | app
116 | └── directives
117 | ├── directive1
118 | │ ├── directive1.html
119 | │ ├── directive1.js
120 | │ └── directive1.sass
121 | └── directive2
122 | ├── directive2.html
123 | ├── directive2.js
124 | └── directive2.sass
125 |
126 | Wyżej przedstawione podejście, może być wykorzystywane niezależnie od wybranej struktury projektu (jednej z powyższych).
127 |
128 | * Istnieje niewielka różnica pomiędzy [ng-boilerplate](http://joshdmiller.github.io/ng-boilerplate/#/home), a strukturami opisywanymi powyżej. W przypadku ng-boilerplate, wszystkie pliki związane z testami jednostkowymi trzymane są w tym samym katalogu, w którym znajduje się dany komponent. Dzięki temu, w przypadku konieczności dokonania zmian, łatwiej znaleźć testy powiązane z komponentem, testy również spełniają rolę dokumentacji oraz pokazują przykłady użycia danego komponentu.
129 |
130 | services
131 | ├── cache
132 | │ ├── cache1.js
133 | │ └── cache1.spec.js
134 | └── models
135 | ├── model1.js
136 | └── model1.spec.js
137 |
138 | * Plik `app.js` zawiera ustawienia dotyczące routingu oraz konfigurację projektu.
139 | * Każdy plik JS powinien zawierać tylko jeden komponent. Plik powinien być nazwany zgodnie z nazwą komponentu.
140 | * Używaj Angularowej struktury szablonów takich, jak [Yeoman](http://yeoman.io), [ng-boilerplate](http://joshdmiller.github.io/ng-boilerplate/#/home).
141 |
142 | Preferuję pierwszą opisywaną przeze mnie strukturę, ponieważ dzięki niej, znalezienie komponentów jest prostsze.
143 |
144 | Konwencje nazewnicze komponentów można znaleźć w każdej sekcji dot. komponentów.
145 |
146 | ## Optymalizuj cykl `$digest`
147 |
148 | * Obserwuj jedynie najistotniejsze zmienne (np. gdy używasz komunikacji w czasie rzeczywistym, nie rób pętli `$digest` przy każdej odebranej wiadomości).
149 | * Staraj się, aby wszelkie wykorzystania `$watch` były najprostsze, jak to tylko możliwe. Skomplikowane i wolne operacje wykonywane wewnątrz jednego `$watch` spowodują spowolnienie całej aplikacji (pętla `$digest` jest wykonywana w jednym wątku, ponieważ JavaScript jest jednowątkowy).
150 | * Dodaj trzeci argument dla funkcji `$timeout`, aby ominąć pętlę cyklu `$digest`, gdy na żadną ze zmiennych nie ma wpływu wywołanie callbacka funkcji `$timeout`.
151 |
152 | ## Inne
153 |
154 | * Używaj:
155 | * `$timeout` zamiast `setTimeout`,
156 | * `$interval` zamiast `setInterval`,
157 | * `$window` zamiast `window`,
158 | * `$document` zamiast `document`,
159 | * `$http` zamiast `$.ajax`
160 |
161 | Dzięki temu, testowanie kodu będzie prostsze i w niektórych przypadkach, uchroni przed nieprzewidzianymi zachowaniami (przykład: gdy zapomniałeś/aś o `$scope.$apply` w `setTimeout`).
162 |
163 | * Zautomatyzuj swój cykl pracy używając narzędzi typu:
164 | * [Yeoman](http://yeoman.io)
165 | * [Grunt](http://gruntjs.com)
166 | * [Bower](http://bower.io)
167 |
168 | * Używaj promises (`$q`) zamiast callbacków. Dzięki temu twój kod będzie bardziej czytelny i czystszy, oraz uchroni cię przed piekłem callbacków.
169 | * Używaj `$resource` zamiast `$http` kiedy to tylko możliwe. Wyższy poziom abstrakcji uchroni cię przed nadmiarem kodu.
170 | * Nie zaśmiecaj `$scope`. Dodawaj tylko te funkcje i zmienne, których używasz w szablonach.
171 | * Preferuj używanie [kontrolerów zamiast `ngInit`](https://github.com/angular/angular.js/pull/4366/files). Jedyne prawidłowe użycie `ngInit` jest wtedy, gdy chcesz nadać alias specjalnym właściwościom `ngRepeat`. Poza tym, powinieneś/powinnaś używać kontrolerów, a nie `ngInit`, aby zainicjować wartości scope'a.
172 | * Nie używaj przedrostka `$` dla nazw zmiennych, właściwości oraz metod. Ten przedrostek jest zarezerwowany jedynie do użytku przez AngularJS.
173 |
174 | # Moduły
175 |
176 | * Nazewnictwo modułów powinno być stosowane zgodnie z lowerCamelCasem. W przypadku, gdy chcemy stworzyć moduł `b` będący podmodułem modułu `a`, możesz wykorzystać przestrzeń nazw: `a.b.`.
177 |
178 | Istnieją dwa najpopularniejsze sposoby na strukturyzowanie modułów:
179 |
180 | 0. Ze względu na funkcjonalność
181 | 0. Ze względu na typ komponentu
182 |
183 | Obecnie nie ma dużej różnicy, jednak pierwsze rozwiązanie jest czystsze. Dodatkowo, jeżeli opóźnione ładowanie modułów jest zaimplementowane (obecnie nie jest w planach AngularJS), poprawi to wydajność aplikacji.
184 |
185 | # Kontrolery
186 |
187 | * Nie manipuluj DOMem wewnątrz kontrolerów, spowoduje to, że kontrolery będą trudniejsze w testowaniu oraz złamie [zasadę SoC](https://en.wikipedia.org/wiki/Separation_of_concerns). Używaj do tego celu dyrektyw.
188 | * Nazewnictwo kontrolerów bazuje na funkcjonalności kontrolera (np. koszyk, strona główna, panel administracyjny) oraz przyrostka `Ctrl`. Kontrolery powinny być nazywane UpperCamelCasem (`HomePageCtrl`, `ShoppingCartCtrl`, `AdminPanelCtrl`, itd.).
189 | * Kontrolery nie powinny być definiowane globalnie (mimo, że AngularJS na to pozwala, zanieczyszczanie globalnej przestrzeni nazw jest złą praktyką).
190 | * Używaj tablicy, aby zdefiniować kontrolery:
191 |
192 | ````javascript
193 | module.controller('MyCtrl', ['dependency1', 'dependency2', ..., 'dependencyn', function (dependency1, dependency2, ..., dependencyn) {
194 | //...body
195 | }]);
196 | ````
197 |
198 | Używanie tego typu deklarowania kontrolerów rozwiązuje problemy z minifikowaniem kodu. Możesz dynamicznie tworzyć tablice zależności, używając do tego narzędziu typu [ng-annotate](https://github.com/olov/ng-annotate) lub zadania grunta [grunt-ng-annotate](https://github.com/mzgol/grunt-ng-annotate).
199 | * Używaj oryginalnych nazw w zależnościach kontrolera. Dzięki temu, kod będzie bardziej czytelny.
200 |
201 | ````javascript
202 | module.controller('MyCtrl', ['$scope', function (s) {
203 | //...body
204 | }]);
205 | ````
206 |
207 | jest mniej czytelne niż:
208 |
209 | ````javascript
210 | module.controller('MyCtrl', ['$scope', function ($scope) {
211 | //...body
212 | }]);
213 | ````
214 |
215 | Powyższa zasada pomaga przede wszystkim w plikach, które są dłuższe i żeby zobaczyć listę zależności, musisz przewijać ekran do góry. Przy okazji, stosowanie pełnych nazw zależności, uchroni przed zapomnieniem, czym jest dana zmienna.
216 |
217 | * Twórz kontrolery tak małe, jak to tylko możliwe. Przenieś wiele razy używane funkcje do usług.
218 | * Komunikuj się pomiędzy różnymi kontrolerami stosując metodę inwokacji (przykładowo, gdy dzieci chcą się skomunikować z rodzicem) lub metodami takimi, jak: `$emit`, $broadcast` oraz `$on`. Emitowane oraz nadwane wiadomości powinne być ograniczone do minimum.
219 | * Stwórz spis wszystkich wiadomości emitowanych (`$emit`) lub nadawanych (`$broadcast`) w aplikacji, aby uniknąć zduplikowanych nazw i możliwych błędów.
220 | * Jeżeli musisz formatować dane w jakikolwiek sposób, przenieś logikę do [filtra](#filtry) i zadeklaruj go, jako zależność dla danego kontrolera:
221 |
222 | ````javascript
223 | module.filter('myFormat', function () {
224 | return function () {
225 | //...body
226 | };
227 | });
228 |
229 | module.controller('MyCtrl', ['$scope', 'myFormatFilter', function ($scope, myFormatFilter) {
230 | //...body
231 | }]);
232 | ````
233 |
234 | # Dyrektywy
235 |
236 | * Nazywaj dyrektywy stosujać lowerCamelCase'a.
237 | * Używaj `scope` zamiast `$scope` wewnątrz funkcji `link`. Podczas kompilacji, `post`/`pre` łączy funkcje, które dotychczas zdefiniowałeś i argumenty zostaną przekazane, kiedy funkcja jest wywoływana. Argumenty te, nie mogą zostać zmienione używając Dependency Injection. Ta technika wykorzystywana jest również w kodzie źródłowym AngularJS.
238 | * Używaj własnych przedrostków dla swoich dyrektyw, aby uniknąć konfliktów z zewnętrznymi bibliotekami.
239 | * Nie używaj przedrostków `ng` oraz `ui`, ponieważ są one zarezerwowane jedynie dla AngularJS oraz AngularJS UI.
240 | * Manipulacja DOMem dozwolona jest jedynie poprzez dyrektywy.
241 | * Twórz odizolowany zakres, gdy tworzysz komponenty wielokrotnego użytku.
242 | * Używaj dyrektyw jako atrybuty lub elementy zamiast komentarzy i klas. Sprawi to, że kod będzie bardziej czytelny.
243 | * Używaj `$scope.$on('$destroy', fn)` do "sprzątania". Przydaje się to w szczególności, gdy opakowujesz zewnętrzną bibliotekę w dyrektywę.
244 | * Nie zapomnij użyć `$sce` w przypadku, gdy masz do czynienia z niezaufanymi treściami.
245 |
246 | # Filtry
247 |
248 | * Używaj lowerCamelCase'a do nazywania swoich filtrów.
249 | * Filtry powinny być tak proste, jak to tylko możliwe. Często są one wywoływane podczas pętli `$digest`, tak więc tworzenie filtrów, które działają wolno, spowolni działanie całej aplikacji.
250 | * Filtry powinien robić jedną rzecz, tworząc je, pamiętaj o ich odseparowaniu. Bardziej skomplikowane manipulacje można uzyskać łącząc istniejące już filtry.
251 |
252 | # Usługi
253 |
254 | * Używaj camelCase'a (lower lub Upper) do nazywania swoich usług.
255 | * Hermetyzuj logikę biznesową w usługach.
256 | * Usługi hermetyzujące logikę biznesową są komponentem typu `service`, a nie `factory`.
257 | * Do cache'owania na poziomie sesji używaj `$cacheFactory`. Powinno się tego używać do cache'owania wyników zapytań oraz dużych obliczeń.
258 |
259 | # Szablony
260 |
261 | * Używaj atrybutów `ng-bind` oraz `ng-cloak` zamiast zwykłego `{{ }}`, aby uniknąć migającej strony podczas ładowania.
262 | * Unikaj pisania skomplikowanych wyrażeń wewnątrz szablonów.
263 | * Jeżeli musisz ładować obrazek dynamicznie, używaj atrybutu `ng-src` zamiast `src` z wartością `{{ }}`.
264 | * Zamiast używania zmiennej w zakresie jako tekst i używania jej jako wartości atrybutu `style` w szablonie z `{{ }}`, używaj dyrektywy `ng-style`, która przyjmuje parametry w postaci obiektu z zakresu z wartościami, przykład:
265 |
266 | ````javascript
267 | $scope.divStyle = {
268 | width: 200;
269 | position: 'relative';
270 | }
271 | ````
272 | ````html
273 | mój pięknie ostylowany div, który będzie działać w IE
274 | ````
275 |
276 | # Routing
277 |
278 | * Używaj `resolve`, aby rozwiązać problemy z zależnościami zanim widok jest wyświetlony.
279 |
280 | # Testy
281 |
282 | Wkrótce...
283 |
284 | Do czasu, aż ta sekcja zostanie uzupełniona, możesz [przeczytać o wzorach testów w AngularJS](https://github.com/daniellmb/angular-test-patterns).
285 |
286 | # Wsparcie
287 |
288 | Celem tego style guide'a jest to, aby był rozwijany przez społeczność, w związku z tym, wszelkie próby udzielenia się są wskazane.
289 |
290 | Przykładowo, możesz pomóc opisując sekcję dotyczącą testów oraz tłumacząc ten style guide na swój język.
291 |
292 | [](https://bitdeli.com/free "Bitdeli Badge")
293 |
--------------------------------------------------------------------------------
/README-ru-ru.md:
--------------------------------------------------------------------------------
1 | [](https://gitter.im/mgechev/angularjs-style-guide?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
2 |
3 | # Введение
4 |
5 | Цель данного руководства — предоставить набор лучших практик и рекомендаций по стилю для AngularJS приложений.
6 |
7 | В работе были использованы следующие источники:
8 |
9 | 0. Исходный код AngularJS.
10 | 0. Мной прочитанные статьи.
11 | 0. Мой собственный опыт.
12 |
13 | **Замечание 1**: это все еще черновик, главная цель которого — это-то, чтобы его развивало сообщество и поэтому восполнение любых пробелов будет принято с благодарностью.
14 |
15 | **Замечание 2**: перед использованием рекомендаций, описанных в данном переводе, убедитесь, что они соответствуют текущей версии оригинала.
16 |
17 | В данном руководстве вы не найдете общих требований к стилю для разработки на JavaScript. Они есть тут:
18 |
19 | 0. [Google's JavaScript style guide](https://google.github.io/styleguide/javascriptguide.xml)
20 | 0. [Mozilla's JavaScript style guide](https://developer.mozilla.org/en-US/docs/Developer_Guide/Coding_Style)
21 | 0. [Douglas Crockford's JavaScript style guide](http://javascript.crockford.com/code.html)
22 | 0. [Airbnb JavaScript style guide](https://github.com/airbnb/javascript)
23 |
24 | При разработке приложений на AngularJS рекомендуется использовать [Google's JavaScript style guide](https://google.github.io/styleguide/javascriptguide.xml).
25 |
26 | На wiki странице GitHub репозитория AngularJS есть похожая секция, созданная [ProLoser](https://github.com/ProLoser), которая находится [здесь](https://github.com/angular/angular.js/wiki).
27 |
28 | # Переводы
29 |
30 | Данный документ является русским переводом рекомендаций. Оригинальный текст на английском языке находится [здесь](https://github.com/mgechev/angularjs-style-guide/blob/master/README.md)
31 |
32 | Также доступны переводы на нижеперечисленных языках:
33 |
34 | - [Немецкий](https://github.com/mgechev/angularjs-style-guide/blob/master/README-de-de.md)
35 | - [Испанский](https://github.com/mgechev/angularjs-style-guide/blob/master/README-es-es.md)
36 | - [Французский](https://github.com/mgechev/angularjs-style-guide/blob/master/README-fr-fr.md)
37 | - [Индонезийский](https://github.com/mgechev/angularjs-style-guide/blob/master/README-id-id.md)
38 | - [Итальянский](https://github.com/mgechev/angularjs-style-guide/blob/master/README-it-it.md)
39 | - [Японский](https://github.com/mgechev/angularjs-style-guide/blob/master/README-ja-jp.md)
40 | - [Корейский](https://github.com/mgechev/angularjs-style-guide/blob/master/README-ko-kr.md)
41 | - [Польский](https://github.com/mgechev/angularjs-style-guide/blob/master/README-pl-pl.md)
42 | - [Португальский](https://github.com/mgechev/angularjs-style-guide/blob/master/README-pt-br.md)
43 | - [Сербский](https://github.com/mgechev/angularjs-style-guide/blob/master/README-sr.md)
44 | - [Сербский латиница](https://github.com/mgechev/angularjs-style-guide/blob/master/README-sr-lat.md)
45 | - [Китайский](https://github.com/mgechev/angularjs-style-guide/blob/master/README-zh-cn.md)
46 | - [Турецкий](https://github.com/mgechev/angularjs-style-guide/blob/master/README-tr-tr.md)
47 |
48 | # Содержание
49 | * [Общие](#general)
50 | * [Файловая структура](#directory-structure)
51 | * [Разметка](#markup)
52 | * [Другое](#others)
53 | * [Модули](#modules)
54 | * [Контроллеры](#controllers)
55 | * [Директивы](#directives)
56 | * [Фильтры](#filters)
57 | * [Сервисы](#services)
58 | * [Шаблоны](#templates)
59 | * [Маршрутизация](#routing)
60 | * [i18n](#i18n)
61 | * [Производительность](#performance)
62 | * [Вклад](#contribution)
63 |
64 | # Общие
65 |
66 | ## Файловая структура
67 |
68 | Так как большое AngularJS приложение состоит из большого количества компонентов, оптимальный способ их структурирования — иерархия каталогов.
69 |
70 | Существует два основных подхода:
71 |
72 | * Сперва разделить по типам компонентов, затем по функциональности.
73 |
74 | В этом случае структура каталогов будет выглядеть примерно так:
75 |
76 | ```
77 | .
78 | ├── app
79 | │ ├── app.js
80 | │ ├── controllers
81 | │ │ ├── home
82 | │ │ │ ├── FirstCtrl.js
83 | │ │ │ └── SecondCtrl.js
84 | │ │ └── about
85 | │ │ └── ThirdCtrl.js
86 | │ ├── directives
87 | │ │ ├── home
88 | │ │ │ └── directive1.js
89 | │ │ └── about
90 | │ │ ├── directive2.js
91 | │ │ └── directive3.js
92 | │ ├── filters
93 | │ │ ├── home
94 | │ │ └── about
95 | │ └── services
96 | │ ├── CommonService.js
97 | │ ├── cache
98 | │ │ ├── Cache1.js
99 | │ │ └── Cache2.js
100 | │ └── models
101 | │ ├── Model1.js
102 | │ └── Model2.js
103 | ├── partials
104 | ├── lib
105 | └── test
106 | ```
107 |
108 | * Сперва разделить по функциональности, затем по типам компонентов.
109 |
110 | Вот как это выглядит:
111 |
112 | ```
113 | .
114 | ├── app
115 | │ ├── app.js
116 | │ ├── common
117 | │ │ ├── controllers
118 | │ │ ├── directives
119 | │ │ ├── filters
120 | │ │ └── services
121 | │ ├── home
122 | │ │ ├── controllers
123 | │ │ │ ├── FirstCtrl.js
124 | │ │ │ └── SecondCtrl.js
125 | │ │ ├── directives
126 | │ │ │ └── directive1.js
127 | │ │ ├── filters
128 | │ │ │ ├── filter1.js
129 | │ │ │ └── filter2.js
130 | │ │ └── services
131 | │ │ ├── service1.js
132 | │ │ └── service2.js
133 | │ └── about
134 | │ ├── controllers
135 | │ │ └── ThirdCtrl.js
136 | │ ├── directives
137 | │ │ ├── directive2.js
138 | │ │ └── directive3.js
139 | │ ├── filters
140 | │ │ └── filter3.js
141 | │ └── services
142 | │ └── service3.js
143 | ├── partials
144 | ├── lib
145 | └── test
146 | ```
147 |
148 | * Если имя каталога состоит из нескольких слов, используйте разделение в стиле lisp:
149 |
150 | ```
151 | app
152 | ├── app.js
153 | └── my-complex-module
154 | ├── controllers
155 | ├── directives
156 | ├── filters
157 | └── services
158 | ```
159 |
160 | * При создании директив достаточно удобно будет сложить все связанные с ней файлы (к примеру, шаблоны, CSS/SASS, JavaScript) в один каталог. Если вы решите использовать этот подход, старайтесь придерживаться его во всём проекте.
161 |
162 | ```
163 | app
164 | └── directives
165 | ├── directive1
166 | │ ├── directive1.html
167 | │ ├── directive1.js
168 | │ └── directive1.sass
169 | └── directive2
170 | ├── directive2.html
171 | ├── directive2.js
172 | └── directive2.sass
173 | ```
174 |
175 | Этот подход может сочетаться с любой из описанных выше структур каталогов.
176 |
177 | * Unit тесты для проверки компонентов должны находиться в том же каталоге, что и сам компонент. В этом случае при изменении компонента вам не придётся долго искать его тесты. Также, при таком подходе, тесты играют роль документации и показывают примеры использования.
178 |
179 | ```
180 | services
181 | ├── cache
182 | │ ├── cache1.js
183 | │ └── cache1.spec.js
184 | └── models
185 | ├── model1.js
186 | └── model1.spec.js
187 | ```
188 |
189 | * Файл `app.js` должен содержать определения маршрутов, конфигурацию и/или начальную инициализацию (если требуется).
190 | * Каждый JavaScript файл должен содержать только один компонент. Имя файла должно соответствовать названию компонента.
191 | * Используйте шаблоны для структуры AngularJS проектов, такие как [Yeoman](http://yeoman.io), [ng-boilerplate](http://joshdmiller.github.io/ng-boilerplate/#/home).
192 |
193 | Соглашения об именовании компонентов будут описаны в соответствующих секциях.
194 |
195 | ## Разметка
196 |
197 | [TLDR;](http://developer.yahoo.com/blogs/ydn/high-performance-sites-rule-6-move-scripts-bottom-7200.html) Расположите скрипты в самом конце файла.
198 |
199 | ```
200 |
201 |
202 |
203 |
204 | MyApp
205 |
206 |
207 |
210 |
211 |
212 |
213 |
214 | ```
215 |
216 | Указывайте атрибуты AngularJS (директивы) после стандартных. Так будет проще отделить элементы фреймворка от HTML-разметки (что, в свою очередь, сильно облегчит поддержку).
217 |
218 | ```
219 |
224 | ```
225 |
226 | Последовательность стандартных HTML атрибутов должна соответствовать следующим [рекомендациям](http://mdo.github.io/code-guide/#html-attribute-order).
227 |
228 | ## Другое
229 |
230 | * Используйте:
231 | * `$timeout` вместо `setTimeout`
232 | * `$interval` вместо `setInterval`
233 | * `$window` вместо `window`
234 | * `$document` вместо `document`
235 | * `$http` вместо `$.ajax`
236 |
237 | Это сделает ваше тестирование гораздо проще и в некоторых случае убережет от неожиданного поведения (например, если вы забудете `$scope.$apply` в `setTimeout`).
238 |
239 | * Автоматизируйте ваши процессы с помощью следующих инструментов:
240 | * [Yeoman](http://yeoman.io)
241 | * [Gulp](http://gulpjs.com)
242 | * [Grunt](http://gruntjs.com)
243 | * [Bower](http://bower.io)
244 |
245 | * Используйте промисы (`$q`) взамен callback'ов. Это сделает ваш код более элегантным и чистым, а также спасет от "callback hell".
246 | * Используйте `$resource` вместо `$http` где это возможно. Более высокий уровень абстракций убережет вас от избыточного кода.
247 | * Используйте AngularJS pre-minifier (такой, как [ngmin](https://github.com/btford/ngmin) или [ng-annotate](https://github.com/olov/ng-annotate)) для избежания проблем после сжатия скриптов.
248 | * Не используйте глобальное пространство имён. Разрешайте все зависимости с помощью Dependency Injection. Это уменьшит количество ошибок и убережёт от обезьяньей работы при тестировании.
249 | * Не используйте глобальное пространство имён. Автоматизаторы Grunt/Gulp могут оборачивать ваш код в самовызывающиеся функции. У обоих есть готовые пакеты [grunt-wrap](https://www.npmjs.com/package/grunt-wrap) и [gulp-wrap](https://www.npmjs.com/package/gulp-wrap/). Как это выглядит (используя Gulp)
250 |
251 | ```Javascript
252 | gulp.src("./src/*.js")
253 | .pipe(wrap('(function(){\n"use strict";\n<%= contents %>\n})();'))
254 | .pipe(gulp.dest("./dist"));
255 | ```
256 | * Не захламляйте ваш `$scope`. Добавляйте только те переменные и функции, который будут использованы в шаблонах.
257 | * Используйте [контроллеры вместо `ngInit`](https://github.com/angular/angular.js/pull/4366/files). Использовать `ngInit` рекомендуется только совместно с директивой `ngRepeat` и только для работы с её служебными свойствами. Во всех остальных случаях `$scope`-переменные должны инициализироваться в контроллерах. Переданные в `ngInit` выражения проходят лексический анализ, парсинг и выполнение интерпретатором сервиса `$parse`. Это может привести к:
258 | - Потере производительности, потому что интерпретатор написан на JavaScript
259 | - Ненужному кешированию обработанных выражений внутри сервиса `$parse`, потому что в подавляющем большинстве случаев выражения, прописанные в `ngInit`, используются только один раз
260 | - Большему риску появления ошибок - вы пишете код, как текстовую строку шаблона, соответственно нет подсветки синтаксиса и других плюшек вашего любимого редактора/IDE
261 | - Невозможности перехватывать run-time ошибки - они просто не будут брошены.
262 | * Не используйте префикс `$` при определении переменных, свойств и методов. Этот префикс зарезервирован для AngularJS.
263 | * При перечислении зависимостей сперва указывайте встроенные, потом дополнительные:
264 |
265 | ```javascript
266 | module.factory('Service', function ($rootScope, $timeout, MyCustomDependency1, MyCustomDependency2) {
267 | return {
268 | //Something
269 | };
270 | });
271 | ```
272 |
273 | # Модули
274 |
275 | * Названия модулей должны соответстовать подходу lowerCamelCase. Для определения иерархии, например, что модуль `b` является подмодулем `a`, используйте пространства имён: `a.b`.
276 |
277 | Существует два основных способа структурирования модулей:
278 |
279 | 0. По функциональности.
280 | 0. По типу компонента.
281 |
282 | На самом деле они не очень то и отличаются, но первый путь выглядит чище. Также, если ленивая загрузка модулей будет когда-нибудь реализована (в настоящее время нет в планах AngularJS) — это улучшит производительность приложения.
283 |
284 | # Контроллеры
285 | * Не изменяйте DOM из контроллеров, это усложнит их тестирование, а также нарушит [Принцип разделения ответственности](https://en.wikipedia.org/wiki/Separation_of_concerns). Используйте для этого директивы.
286 | * Именовать контроллер следует так, чтобы его имя состояло из части, описывающей то, чем он занимается (для примера: корзина, домашняя страница, админ-панель) и постфикса `Ctrl`.
287 | * Контроллеры - это стандартные [конструкторы](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor), соответвенно их имена записываются в UpperCamelCase (`HomePageCtrl`, `ShoppingCartCtrl`, `AdminPanelCtrl`, и т.д.).
288 | * Контроллеры не должны быть объявлены в глобальном пространстве (хотя AngularJS и позволяет использовать этот подход, он засоряет глобальное пространство имён, а потому считается нежелательным).
289 | * Используйте следующий синтаксис для объявления контроллеров:
290 |
291 | ```JavaScript
292 | function MyCtrl(dependency1, dependency2, ..., dependencyn) {
293 | // ...
294 | }
295 | module.controller('MyCtrl', MyCtrl);
296 | ```
297 |
298 |
299 | Чтобы избежать проблем с минификацией файлов, вы можете автоматически генерировать определение с синтаксисом массива, используя инструменты типа [ng-annotate](https://github.com/olov/ng-annotate) (и задачи для grunt [grunt-ng-annotate](https://github.com/mzgol/grunt-ng-annotate)).
300 |
301 | * Настоятельно рекомендуется использовать синтаксис `controller as`:
302 |
303 | ```
304 |
305 | {{ main.title }}
306 |
307 | ```
308 |
309 | ```JavaScript
310 | app.controller('MainCtrl', MainCtrl);
311 |
312 | function MainCtrl () {
313 | this.title = 'Some title';
314 | };
315 | ```
316 |
317 | Основные плюшки:
318 | * Создаётся 'изолированный' компонент - привязанные свойства не являются частью цепочки прототипов `$scope`. Это хороший подход, поскольку наследование прототипов `$scope` имеет серьёзные недостатки (вероятно, именно поэтому это было выкинуто из Angular 2):
319 | * Тяжело отследить, откуда к нам пришли данные.
320 | * Изменение значений `$scope` может затронуть участки кода, которые не должны были быть затронуты.
321 | * Гораздо тяжелее рефакторить.
322 | * '[Правило точки](http://jimhoskins.com/2012/12/14/nested-scopes-in-angularjs.html)'.
323 | * `$scope` не используется, если нам не нужны специфичные операции (типа `$scope.$broadcast`). Это хорошая подготовка к AngularJS V2.
324 | * Синтаксис значительно ближе к 'ванильному' конструктору JavaScript
325 |
326 | Больше о подходе `controller as` здесь: [digging-into-angulars-controller-as-syntax](http://toddmotto.com/digging-into-angulars-controller-as-syntax/)
327 |
328 | * При использовании синтаксиса массива используйте оригинальные имена для зависимостей контроллера. Код будет более читабельным:
329 |
330 | ```JavaScript
331 | function MyCtrl(s) {
332 | // ...
333 | }
334 |
335 | module.controller('MyCtrl', ['$scope', MyCtrl]);
336 | ```
337 |
338 | читается гораздо хуже, чем:
339 |
340 | ```JavaScript
341 | function MyCtrl($scope) {
342 | // ...
343 | }
344 | module.controller('MyCtrl', ['$scope', MyCtrl]);
345 | ```
346 |
347 | Особенно это актуально для больших файлов со множеством строк кода, который придется проскролить весь, чтобы понять, что есть что. В итоге можно легко забыть, какой зависимости отвечает та или иная переменная.
348 |
349 | * Держите контроллеры настолько маленькими на сколько это возможно. Вынесите общие функции в сервисы.
350 | * Не помещайте бизнес-логику в контроллеры. Вынесите её в сервис, как `model`.
351 | Пример:
352 |
353 | ```Javascript
354 | //Это часто наблюдаемый подход (и хороший пример "как не надо делать") использования бизнес-логики в контроллерах.
355 | angular.module('Store', [])
356 | .controller('OrderCtrl', function ($scope) {
357 |
358 | $scope.items = [];
359 |
360 | $scope.addToOrder = function (item) {
361 | $scope.items.push(item);//--> Бизнес-логика внутри контроллера
362 | };
363 |
364 | $scope.removeFromOrder = function (item) {
365 | $scope.items.splice($scope.items.indexOf(item), 1);//--> Бизнес-логика внутри контроллера
366 | };
367 |
368 | $scope.totalPrice = function () {
369 | return $scope.items.reduce(function (memo, item) {
370 | return memo + (item.qty * item.price);//--> Бизнес-логика внутри контроллера
371 | }, 0);
372 | };
373 | });
374 | ```
375 |
376 | Если же мы вынесем бизнес-логику в сервис типа 'model', контроллер будет выглядеть так (для примера имплементации сервиса обратитесь к примеру 'Вся бизнес-логика должна размещаться в сервисах'):
377 |
378 | ```Javascript
379 | //сервис Order используется в качестве 'model'
380 | angular.module('Store', [])
381 | .controller('OrderCtrl', function (Order) {
382 |
383 | $scope.items = Order.items;
384 |
385 | $scope.addToOrder = function (item) {
386 | Order.addToOrder(item);
387 | };
388 |
389 | $scope.removeFromOrder = function (item) {
390 | Order.removeFromOrder(item);
391 | };
392 |
393 | $scope.totalPrice = function () {
394 | return Order.total();
395 | };
396 | });
397 | ```
398 |
399 | Использование бизнес-логики или хранение состояния приложения в контроллерах не рекомендуется по следующим причинам:
400 | * Контроллеры инициализируются для каждого `view` и уничтожаются с ним же
401 | * Контроллеры нельзя переиспользовать - они завязаны на `view`
402 | * Контроллеры не могут быть использованы при внедрении зависимости (dependency injection)
403 |
404 | * Организовывайте коммуникацию между контроллерами используя вызовы методов (например когда дети хотят связаться с родителями) или методы `$emit`, `$broadcast` и `$on`. Количество `$emit` и `$broadcast` сообщений должно быть сведено к минимуму.
405 | * Создайте и поддерживайте список со всеми сообщениями пересылаемыми с помощью `$emit`, `$broadcast`, чтобы избежать коллизий имён и прочих возможных ошибок.
406 |
407 | Пример:
408 |
409 | ```JavaScript
410 | // app.js
411 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
412 | Custom events:
413 | - 'authorization-message' - description of the message
414 | - { user, role, action } - data format
415 | - user - a string, which contains the username
416 | - role - an ID of the role the user has
417 | - action - specific ation the user tries to perform
418 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
419 | ```
420 |
421 | * Если вам нужно отформатировать данные, перенесите логику форматирования в [фильтр](#filters) и укажите его как зависимость:
422 |
423 | ```JavaScript
424 | function myFormat() {
425 | return function () {
426 | // ...
427 | };
428 | }
429 | module.filter('myFormat', myFormat);
430 |
431 | function MyCtrl($scope, myFormatFilter) {
432 | // ...
433 | }
434 |
435 | module.controller('MyCtrl', MyCtrl);
436 | ```
437 |
438 | * При использовании вложенных контроллеров не забывайте про "nested scoping" (синтаксис `controllerAs`):
439 |
440 | **app.js**
441 | ```javascript
442 | module.config(function ($routeProvider) {
443 | $routeProvider
444 | .when('/route', {
445 | templateUrl: 'partials/template.html',
446 | controller: 'HomeCtrl',
447 | controllerAs: 'home'
448 | });
449 | });
450 | ```
451 | **HomeCtrl**
452 | ```javascript
453 | function HomeCtrl() {
454 | this.bindingValue = 42;
455 | }
456 | ```
457 | **template.html**
458 | ```
459 |
460 | ```
461 |
462 | # Директивы
463 |
464 | * Называйте ваши директивы используя lowerCamelCase.
465 | * Используйте `scope` вместо `$scope` в функции `link`. При использовании функций compile, post/pre link им будут переданы предопределённые аргументы, которые нельзя будет изменить, используя DI. Такой стиль используется и внутри самого AngularJS.
466 | * Используйте кастомные префиксы для ваших директив во избежание коллизий со сторонними библиотеками.
467 | * Не используйте префиксы `ng` или `ui`, так как они зарезервированы для использования в AngularJS и AngularJS UI.
468 | * Манипуляции с DOM должны производиться только с помощью директив.
469 | * Создавайте изолированный scope когда вы разрабатываете переиспользуемые компоненты.
470 | * Определяйте директивы через атрибуты или элементы, не используйте для этого классы или комментарии. Код будет куда более читабельным.
471 | * Делайте `$scope.$on('$destroy', fn)` для очистки. Особенно актуально при оборачивании сторонних плагинов в директивы.
472 | * Не забывайте про `$sce`, когда работаете с непроверенным контентом.
473 |
474 | # Фильтры
475 |
476 | * Называйте ваши фильтры используя lowerCamelCase.
477 | * Фильтры должны быть максимально простыми. Они часто вызываются во время цикла `$digest`, поэтому один медленный фильтр может значительно замедлить все приложение.
478 | * Один фильтр - одно простое действие. Несколько действий - несколько фильтров через `|`.
479 |
480 | # Сервисы
481 |
482 | В этой секции описывается информация о сервисах в AngularJS. Способ объявления (например, `.factory`, `.service`) не важен, если не указано отдельно.
483 |
484 | * Используйте camelCase при определении имён сервисов.
485 | * UpperCamelCase (PascalCase) должен использоваться для сервисов, используемых в качестве конструкторов:
486 |
487 | ```JavaScript
488 | function MainCtrl($scope, User) {
489 | $scope.user = new User('foo', 42);
490 | }
491 |
492 | module.controller('MainCtrl', MainCtrl);
493 |
494 | function User(name, age) {
495 | this.name = name;
496 | this.age = age;
497 | }
498 |
499 | module.factory('User', function () {
500 | return User;
501 | });
502 | ```
503 |
504 | * lowerCamelCase для всех остальных сервисов.
505 |
506 | * Вся бизнес-логика должна размещаться в сервисах. Хорошим подходом является использование принципа `model`:
507 |
508 | ```Javascript
509 | //Order is the 'model'
510 | angular.module('Store')
511 | .factory('Order', function () {
512 | var add = function (item) {
513 | this.items.push (item);
514 | };
515 |
516 | var remove = function (item) {
517 | if (this.items.indexOf(item) > -1) {
518 | this.items.splice(this.items.indexOf(item), 1);
519 | }
520 | };
521 |
522 | var total = function () {
523 | return this.items.reduce(function (memo, item) {
524 | return memo + (item.qty * item.price);
525 | }, 0);
526 | };
527 |
528 | return {
529 | items: [],
530 | addToOrder: add,
531 | removeFromOrder: remove,
532 | totalPrice: total
533 | };
534 | });
535 | ```
536 |
537 | Обратитесь к примеру 'Не помещайте бизнес-логику в контроллеры', в нём даны образцы кода "как не надо делать".
538 | * Если сервис является конструктором, используйте `service` вместо `factory`. Это позволит использовать классическое наследование через прототипы:
539 |
540 | ```JavaScript
541 | function Human() {
542 | //body
543 | }
544 | Human.prototype.talk = function () {
545 | return "I'm talking";
546 | };
547 |
548 | function Developer() {
549 | //body
550 | }
551 | Developer.prototype = Object.create(Human.prototype);
552 | Developer.prototype.code = function () {
553 | return "I'm coding";
554 | };
555 |
556 | myModule.service('Human', Human);
557 | myModule.service('Developer', Developer);
558 |
559 | ```
560 | * Для кеширования на уровне сессии можно использовать `$cacheFactory`. Этот метод подходит для кеширования результатов сложных вычислений или каких-либо запросов.
561 | * Если сервис нуждается в настройке при старте приложения, определяйте его через `provider`, а затем конфигурируйте через коллбек `config`:
562 |
563 | ```JavaScript
564 | angular.module('demo', [])
565 | .config(function ($provide) {
566 | $provide.provider('sample', function () {
567 | var foo = 42;
568 | return {
569 | setFoo: function (f) {
570 | foo = f;
571 | },
572 | $get: function () {
573 | return {
574 | foo: foo
575 | };
576 | }
577 | };
578 | });
579 | });
580 |
581 | var demo = angular.module('demo');
582 |
583 | demo.config(function (sampleProvider) {
584 | sampleProvider.setFoo(41);
585 | });
586 | ```
587 |
588 | # Шаблоны
589 |
590 | * Используйте `ng-bind` или `ng-cloak` вместо простого `{{ }}`, чтоб не показывать выражения до обработки их AngularJS.
591 | * Избегайте написания сложного кода в шаблонах.
592 | * Когда вам нужно динамически установить атрибут `src` у картинки, используйте `ng-src` вместо `src` с `{{ }}` внутри.
593 | * Когда вам нужно динамически установить атрибут `href` в теге ссылки, используйте `ng-href` вместо `href` с `{{ }}` внутри.
594 | * Вместо использования строковой переменной в scope и использовании ее в атрибуте `style` через шаблон `{{ }}`, используйте директиву `ng-style` с объектом в scope переменной, как значение:
595 |
596 | ```HTML
597 |
605 |
606 | my beautifully styled div which will work in IE
;
607 | ```
608 |
609 | # Маршрутизация
610 |
611 | * Используйте `resolve` для разрешения зависимостей перед тем, как представление будет показано.
612 | * Избегайте использования REST-запросов внутри `resolve`. Запросы должны размещаться в соответствующих сервисах. Это позволит использовать кеширование, а также следовать принципу разделения ответственности (Separation of concerns).
613 |
614 | # i18n
615 |
616 | * Начиная с версии 1.4.0 AngularJS содержит встроенные инструменты i18n. При работе с предыдущими версиями (<1.4.0) используйте [`angular-translate`](https://github.com/angular-translate/angular-translate).
617 |
618 | # Производительность
619 |
620 | * Оптимизируйте цикл `$digest`
621 |
622 | * Следите (watch) только за теми переменными, где это действительно необходимо. Если требуется явно запустить цикл `$digest` (это должны быть ну очень исключительные случаи), запускайте его только в тех местах, где это действительно необходимо. К примеру, при использовании коммуникации в реальном времени обычно нет нужды запускать цикл `$digest` для каждого полученного сообщения.
623 | * Для контента, который меняется только раз, используйте одноразовые watch. Они есть в AngularJS >= 1.3.0. При использовании более старых версий можно использовать набор директив [`bindonce`](https://github.com/Pasvaz/bindonce).
624 | ```html
625 |
626 | {{ ::main.things }}
627 |
628 | ```
629 | или
630 | ```html
631 |
632 | ```
633 | После этого, для `main.things` не будет создано **ни одного** watch и любые дальнейшие изменения `main.things` не будет отражены на странице.
634 | * Сделайте вычисления в `$watch` максимально простыми. Любые сложные и медленные вычисления в `$watch` замедляют выполнение всего приложения (цикл `$digest` работает в одном потоке, потому что JavaScript однопоточный).
635 | * При отслеживании коллекций с помощью `$watch` используйте глубокое отслеживание только если это действительно необходимо. Обычно достаточно использовать `$watchCollection`, который выполняет простую проверку свойств только первого уровня наблюдаемого объекта.
636 | * При вызове функции `$timeout` устанавливайте третий параметр в false, если функция обратного вызова не изменяет отслеживаемые переменные. В этом случае `$digest` не будет вызван после выполнения функции.
637 | * При работе с редко изменяемыми большими коллекциями, [используйте неизменяемые структуры данных](http://blog.mgechev.com/2015/03/02/immutability-in-angularjs-immutablejs).
638 |
639 | * Не забывайте про способы уменьшения количества запросов к серверу. Одним из них является объединение/кеширование шаблонов в один файл, к примеру используя [grunt-html2js](https://github.com/karlgoldstein/grunt-html2js) / [gulp-html2js](https://github.com/fraserxu/gulp-html2js). [Здесь](http://ng-learn.org/2014/08/Populating_template_cache_with_html2js/) и [здесь](http://slides.com/yanivefraim-1/real-world-angularjs#/34) есть подробная информация. Эффект особенно ощутим, если проект содержит много отдельных файлов шаблонов небольшого размера.
640 |
641 | # Вклад
642 |
643 | Поскольку это руководство должно писаться сообществом, любой вклад в его развитие крайне приветствуется.
644 | К примеру, вы можете заняться секцией "Тестирование" или переводом всего документа на ваш язык.
645 |
--------------------------------------------------------------------------------
/README-sr-lat.md:
--------------------------------------------------------------------------------
1 | #Uvod
2 |
3 | Cilj ovog "style guide" vodiča je da predstavi set najboljih praksi i smernica za jednu AngularJS aplikaciju.
4 | Ove najbolje prakse su prikupljene od:
5 |
6 | 0. AngularJS izvornog koda
7 | 0. Izvornog koda ili članaka koje sam pročitao
8 | 0. Ličnog iskustva
9 |
10 | **Nota**: ovo je još uvek radna verzija, njen glavni cilj je da bude "community-driven" zato ispunjavanje praznina će biti veoma cenjeno od strane cele zajednice.
11 |
12 | U ovom vodiču nećete naći uobičajene preporuke za JavaScript programiranje. Takve se mogu naći na:
13 |
14 | 0. [Google's JavaScript style guide](https://google.github.io/styleguide/javascriptguide.xml)
15 | 0. [Mozilla's JavaScript style guide](https://developer.mozilla.org/en-US/docs/Developer_Guide/Coding_Style)
16 | 0. [Douglas Crockford's JavaScript style guide](http://javascript.crockford.com/code.html)
17 |
18 | Za AngularJS razvoj preporučen je [Google's JavaScript style guide](https://google.github.io/styleguide/javascriptguide.xml).
19 |
20 | Na AngularJS's GitHub wiki-u postoji slična sekcija od [ProLoser](https://github.com/ProLoser), možete je naći na [here](https://github.com/angular/angular.js/wiki).
21 |
22 | #Sadržaj
23 | * [Uopšteno](#uopšteno)
24 | * [Struktura Direktorijuma](#struktura-direktorijuma)
25 | * [Optimizuj ciklus obrade](#optimizuj-ciklus-obrade)
26 | * [Ostalo](#ostalo)
27 | * [Moduli](#moduli)
28 | * [Kontroleri](#kontroleri)
29 | * [Direktive](#direktive)
30 | * [Filteri](#filteri)
31 | * [Servisi](#servisi)
32 | * [Šabloni](#šabloni)
33 | * [Rutiranje](#rutiranje)
34 |
35 | #Uopšteno
36 |
37 | ## Struktura Direktorijuma
38 |
39 | Kako velike AngularJS aplikacije imaju mnogo komponenti najbolje je da se iste organizuju u strukturi direktorijuma.
40 | Postoje dva pristupa:
41 |
42 | * Kreiranje primarnog grupisanja prema tipu komponente a zatim sekundarno grupisanje prema funkcionalnosti.
43 |
44 | U ovom slučaju struktura direktorijuma bi izgledala ovako:
45 |
46 | .
47 | ├── app
48 | │ ├── app.js
49 | │ ├── controllers
50 | │ │ ├── page1
51 | │ │ │ ├── FirstCtrl.js
52 | │ │ │ └── SecondCtrl.js
53 | │ │ └── page2
54 | │ │ └── ThirdCtrl.js
55 | │ ├── directives
56 | │ │ ├── page1
57 | │ │ │ └── directive1.js
58 | │ │ └── page2
59 | │ │ ├── directive2.js
60 | │ │ └── directive3.js
61 | │ ├── filters
62 | │ │ ├── page1
63 | │ │ └── page2
64 | │ └── services
65 | │ ├── CommonService.js
66 | │ ├── cache
67 | │ │ ├── Cache1.js
68 | │ │ └── Cache2.js
69 | │ └── models
70 | │ ├── Model1.js
71 | │ └── Model2.js
72 | ├── lib
73 | └── test
74 |
75 | * Kreiranje primarnog grupisanja prema funkcionalnosti a zatim sekundarno grupisanje prema tipu komponente.
76 |
77 | Ovde je njen raspored:
78 |
79 | .
80 | ├── app
81 | │ ├── app.js
82 | │ ├── common
83 | │ │ ├── controllers
84 | │ │ ├── directives
85 | │ │ ├── filters
86 | │ │ └── services
87 | │ ├── page1
88 | │ │ ├── controllers
89 | │ │ │ ├── FirstCtrl.js
90 | │ │ │ └── SecondCtrl.js
91 | │ │ ├── directives
92 | │ │ │ └── directive1.js
93 | │ │ ├── filters
94 | │ │ │ ├── filter1.js
95 | │ │ │ └── filter2.js
96 | │ │ └── services
97 | │ │ ├── service1.js
98 | │ │ └── service2.js
99 | │ └── page2
100 | │ ├── controllers
101 | │ │ └── ThirdCtrl.js
102 | │ ├── directives
103 | │ │ ├── directive2.js
104 | │ │ └── directive3.js
105 | │ ├── filters
106 | │ │ └── filter3.js
107 | │ └── services
108 | │ └── service3.js
109 | ├── lib
110 | └── test
111 |
112 | * Kada kreirate direktivu može biti korisno da se stave sve povezane datoteke sa datom direktivom (n.p. šabloni, CSS/SASS datoteke, JavaScript) u jedan direktorijum. Ako izaberete ovaj stil budite kozistentni i koristite ga svuda u vašem projektu.
113 |
114 | app
115 | └── directives
116 | ├── directive1
117 | │ ├── directive1.html
118 | │ ├── directive1.js
119 | │ └── directive1.sass
120 | └── directive2
121 | ├── directive2.html
122 | ├── directive2.js
123 | └── directive2.sass
124 |
125 | Ovaj pristup se moze kombinovati sa obe verzije gornje strukture direktorijuma.
126 | * Još jedna blaga varijacija na obe strukture direktorijuma je ona korišćena u [ng-boilerplate](http://joshdmiller.github.io/ng-boilerplate/#/home). U njoj "unit" testovi za datu komponentu se nalaze u istom direktorijumu kao i sama komponenta. Na ovaj način kada napravite neku promenu u datoj komponenti lakše je naći odgovarajuće testove, testovi takođe služe kao dokumentacija i prikazuju "uses cases".
127 |
128 | services
129 | ├── cache
130 | │ ├── cache1.js
131 | │ └── cache1.spec.js
132 | └── models
133 | ├── model1.js
134 | └── model1.spec.js
135 |
136 | * Datoteka `app.js` sadrži definiciju ruta, konfiguraciju i/ili "manual bootstrap" (ukoliko je neophodan).
137 | * Svaka JavaScript datoteka trebalo bi da sadrži samo jednu komponentu. Datoteka bi trebalo da bude imenovana prema imenu komponente.
138 | * Koristi šablon strukture Angular projekta kao [Yeoman](http://yeoman.io), [ng-boilerplate](http://joshdmiller.github.io/ng-boilerplate/#/home).
139 |
140 | Ja više preferiram prvu strukturu jer omogućava lakse pronalaženje uobičajenih komponenti.
141 |
142 | Konvencije oko imenovanje komponenti se mogu naći u svakoj sekciji koja opisuje datu komponentu.
143 |
144 | ## Optimizuj ciklus obrade
145 |
146 | * Posmatraj samo najznačajnije promenjive (na primer: kada se koristi "real-time" komunikacija, ne pozivaj petlju obrade u svakoj primljenoj poruci).
147 | * Pravi proračune u `$watch` što je moguće jednostavnijim. Postavljanje zahtevne i spore kalkulacije u jednom `$watch` će usporiti celokupnu aplikaciju ($digest petlja se izvršava u jednoj niti iz razloga "single-threaded" prirode JavaScript-a).
148 |
149 | ## Ostalo
150 |
151 | * Koristi:
152 | * `$timeout` umesto `setTimeout`
153 | * `$window` umesto `window`
154 | * `$document` umesto `document`
155 | * `$http` umesto `$.ajax`
156 |
157 | Ovo će učiniti testiranje mnogo lakšim a u nekim slučajevima i preduprediti neočekivano ponašanje (na primer, ako ste propustili `$scope.$apply` u `setTimeout`).
158 |
159 | * Automatizujte vaš proces rada koristeći alate kao što su:
160 | * [Yeoman](http://yeoman.io)
161 | * [Grunt](http://gruntjs.com)
162 | * [Bower](http://bower.io)
163 |
164 | * Koristite "promises" (`$q`) umesto "callbacks". Ovo će učiniti da vaš kod izgleda elegantnije, i sačuvaće vas od "callback" pakla.
165 | * Koristite `$resource` umesto `$http` kad god je to moguće. Viši nivo abstrakcije spašava vas od nepotrebnog viška.
166 | * Koristite AngularJS "pre-minifier" (like [ngmin](https://github.com/btford/ngmin) ili [ng-annotate](https://github.com/olov/ng-annotate)) kao prevenciju problema posle "minification".
167 | * Ne koristite globalne promenjive. Razrešite sve zavisnosti koristeći "Dependency Injection".
168 | * Ne zagađujte vaš `$scope`. Dodajte samo one funkcije ili promenjive koje se koriste unutar datog šablona.
169 | * Koristite kontrolere umesto `ngInit`.
170 |
171 | #Moduli
172 |
173 | Postoje dva uobičajena načina da se struktuiraju moduli:
174 |
175 | 0. Prema funkcionalnosti
176 | 0. Prema tipu komponente
177 |
178 | Trenutno nema veće razlike, ali prvi način izgleda urednije. Takođe, ako "lazy-loading" moduli su implementirani (trenutno nisu u AngularJS planu razvoja), to će poboljšati performanse applikacije.
179 |
180 | #Kontroleri
181 |
182 | * Ne menjajte DOM u vašim kontrolerima. Umesto toga koristite direktive.
183 | * Imenovanje kontrolera se vrši prema njegovoj funkcionalnosti (na primer: shopping cart, homepage, admin panel) i dodatka `Ctrl` na kraju imena. Imena kontrolera su zapiasna u "UpperCamelCase" formatu (`HomePageCtrl`, `ShoppingCartCtrl`, `AdminPanelCtrl`, itd.).
184 | * Kontroleri ne bi trebalo da budu definisani kao globalni (bez obzira što AngularJS to dozvoljava, loša je praksa da se zagadi global "namespace").
185 | * Koristi syntaksu niza u definiciji kontrolera:
186 |
187 |
188 |
189 | module.controller('MyCtrl', ['dependency1', 'dependency2', ..., 'dependencyn', function (dependency1, dependency2, ..., dependencyn) {
190 | //...body
191 | }]);
192 |
193 |
194 | Korišćenje ovog tipa definicija izbegava probleme sa "minification". Možete automatski generisati niz definicija od jedne standardne koristeći alate kao što su [ng-annotate](https://github.com/olov/ng-annotate) (i grunt zadatak [grunt-ng-annotate](https://github.com/mzgol/grunt-ng-annotate)).
195 | * Koristite originalne nazive zavisnosti kontrolera. Ovo će vam pomoći da proizvedete čitljiviji kod:
196 |
197 |
198 |
199 | module.controller('MyCtrl', ['$scope', function (s) {
200 | //...body
201 | }]);
202 |
203 |
204 | je manje čitljivo od:
205 |
206 |
207 | module.controller('MyCtrl', ['$scope', function ($scope) {
208 | //...body
209 | }]);
210 |
211 |
212 | Ovo je posebno primenjivo na datoteku koja ima toliko koda da ćete morati da se vertikalno krećete kroz isti. Ovo će najverovatnije dovesti do toga da zaboravite koja je promenjiva vezana za koju zavisnost.
213 |
214 | * Kreirajte što je moguće "tanje" kontrolere. Abstraktujte često korišćene funkcije u servis.
215 | * Komunicirajte unutar različitih kontorlera korišćenjem pozivanjem metoda (moguće kada deca žele da komuniciraju sa roditeljima) ili `$emit`, `$broadcast` i `$on` metode. "Emitted" i "broadcasted" poruke treba držati na minimumu.
216 | * Napravite listu svih poruka koje se prenose korišćenjem `$emit`, `$broadcast` i pažljivo ih održavajte iz razloga kolizije naziva i mogućih grešaka.
217 | * Kada je potrebno da formatirate podatke enkapsulirajte logiku formatiranja unutar [filtera](#filteri) i deklarišite ih kao zavisnost:
218 |
219 |
220 | module.filter('myFormat', function () {
221 | return function () {
222 | //body...
223 | };
224 | });
225 |
226 | module.controller('MyCtrl', ['$scope', 'myFormatFilter', function ($scope, myFormatFilter) {
227 | //body...
228 | }]);
229 |
230 | #Direktive
231 |
232 | * Imenujte svoje direktive koristeći "lowerCamelCase"
233 | * Koristite `scope` umesto `$scope` u vašoj "link" funkciji. U "compile", post/pre "link" funkcijama već ste definisali argumente koji će biti prosleđeni prilikom poziva funkcije, nećete moći da ih promenite koristeći DI (Dependency Injection). Ovaj stil je takođe korišćen unutar AngularJS izvornog koda.
234 | * Koristite "custom" prefikse za vaše direktive da bi sprečili koliziju imena sa tuđim bibljotekama.
235 | * Nemojte koristiti `ng` ili `ui` prefikse jer su ovi rezervisani za AngularJS i AngularJS UI upotrebu.
236 | * DOM manipulacije moraju biti izvršene samo kroz direktive.
237 | * Kreirajte izlovoano područje kada razvijate komponente za višestruku upotrebu.
238 |
239 | #Filteri
240 |
241 | * Imenujte vaše filtere koristeći "lowerCamelCase"
242 | * Kreirajte vaše filtere što je moguće "lakšim". Oni se zovu često tokom `$digest` petlje pa kreiranje sporih filtera će usporiti vašu aplikaciju.
243 |
244 | #Servisi
245 |
246 | * Koristite "camelCase (lower or upper)" za nazive vaših servisa.
247 | * Enkapsulirajte biznis logiku unutar servisa.
248 | * Servisi koji uokviruju biznis logiku su poželjno `service` umesto `factory`
249 | * Za "session-level" keš možete koristiti `$cacheFactory`. Ovo bi trebalo koristiti za keširanje rezultata zahteva ili kompleksnih proračuna.
250 |
251 | #Šabloni
252 |
253 | * Koristite `ng-bind` ili `ng-cloak` umesto prostog `{{ }}` da bi sprečili treptanje sadržaja.
254 | * Izbegavajte pisanje kompleksnog koda unutar šablona.
255 | * Kada je potrebno da dinamički postavitre `src` slike koristite `ng-src` umesto `src` sa `{{}}` šablonom.
256 | * Umesto korišćenja "scope" promenjive kao tekst i koristiti ga sa `style` atributom sa `{{ }}`, koristite direktivu `ng-style` sa "object-like" parametrima i "scope" promenjive kao vrednosti:
257 |
258 | ...
259 | $scope.divStyle = {
260 | width: 200,
261 | position: 'relative'
262 | };
263 | ...
264 |
265 | my beautifully styled div which will work in IE
;
266 |
267 | #Rutiranje
268 |
269 | * Koristite `resolve` da razložite zavisnosti pre nego se prikaže "view".
270 |
--------------------------------------------------------------------------------
/README-sr.md:
--------------------------------------------------------------------------------
1 | #Увод
2 |
3 | Циљ овог "style guide" водича је да се представи сет најбољих пракси и смерница за једну AngularJS апликацију.
4 | Ове најбоље праксе су прикупљене од:
5 |
6 | 0. AngularJS ижворног кода
7 | 0. Изворног кода или чланака које сам прочитао
8 | 0. Личног искуства
9 |
10 | **Нота**: ово је још увек радна верзија, њен главни циљ је да буде "community-driven" зато ће испуњавање празнина бити веома цењено од стране целе заједнице.
11 |
12 | У овом водичу нећете наћи уобичајене препоруке за JavaScript програмирање. Такве се могу наћи на:
13 |
14 | 0. [Google's JavaScript style guide](https://google.github.io/styleguide/javascriptguide.xml)
15 | 0. [Mozilla's JavaScript style guide](https://developer.mozilla.org/en-US/docs/Developer_Guide/Coding_Style)
16 | 0. [Douglas Crockford's JavaScript style guide](http://javascript.crockford.com/code.html)
17 |
18 | За AngularJS развој препоручен је [Google's JavaScript style guide](https://google.github.io/styleguide/javascriptguide.xml).
19 |
20 | На AngularJS's GitHub wiki-у постоји слична секција од [ProLoser](https://github.com/ProLoser), možete je naći na [here](https://github.com/angular/angular.js/wiki).
21 |
22 | #Садржај
23 | * [Уопштено](#уопштено)
24 | * [Структура Директоријума](#структура-директоријума)
25 | * [Оптимизуј циклус обраде](#оптимизуј-циклус-обраде)
26 | * [Остало](#остало)
27 | * [Модули](#модули)
28 | * [контролери](#контролери)
29 | * [Директиве](#директиве)
30 | * [Филтери](#филтери)
31 | * [Сервиси](#сервиси)
32 | * [Шаблони](#шаблони)
33 | * [Рутирање](#рутирање)
34 |
35 | #Уопштено
36 |
37 | ## Структура Директоријума
38 |
39 | Како велике AngularJS апликације имају много компоненти најбоље је да се исте организују у структури директоријума.
40 | Постоје два приступа:
41 |
42 | * Креирање примарног груписања према типу компоненте а затиим секундарно груписање према функционалности.
43 |
44 | У овом случају структура директоријума би изгледала овако:
45 |
46 | .
47 | ├── app
48 | │ ├── app.js
49 | │ ├── controllers
50 | │ │ ├── page1
51 | │ │ │ ├── FirstCtrl.js
52 | │ │ │ └── SecondCtrl.js
53 | │ │ └── page2
54 | │ │ └── ThirdCtrl.js
55 | │ ├── directives
56 | │ │ ├── page1
57 | │ │ │ └── directive1.js
58 | │ │ └── page2
59 | │ │ ├── directive2.js
60 | │ │ └── directive3.js
61 | │ ├── filters
62 | │ │ ├── page1
63 | │ │ └── page2
64 | │ └── services
65 | │ ├── CommonService.js
66 | │ ├── cache
67 | │ │ ├── Cache1.js
68 | │ │ └── Cache2.js
69 | │ └── models
70 | │ ├── Model1.js
71 | │ └── Model2.js
72 | ├── lib
73 | └── test
74 |
75 | * Креиранје примарног груписања према функционалнисти а затим секундарно груписање према типу компоненте.
76 |
77 | Овде је њен респоред:
78 |
79 | .
80 | ├── app
81 | │ ├── app.js
82 | │ ├── common
83 | │ │ ├── controllers
84 | │ │ ├── directives
85 | │ │ ├── filters
86 | │ │ └── services
87 | │ ├── page1
88 | │ │ ├── controllers
89 | │ │ │ ├── FirstCtrl.js
90 | │ │ │ └── SecondCtrl.js
91 | │ │ ├── directives
92 | │ │ │ └── directive1.js
93 | │ │ ├── filters
94 | │ │ │ ├── filter1.js
95 | │ │ │ └── filter2.js
96 | │ │ └── services
97 | │ │ ├── service1.js
98 | │ │ └── service2.js
99 | │ └── page2
100 | │ ├── controllers
101 | │ │ └── ThirdCtrl.js
102 | │ ├── directives
103 | │ │ ├── directive2.js
104 | │ │ └── directive3.js
105 | │ ├── filters
106 | │ │ └── filter3.js
107 | │ └── services
108 | │ └── service3.js
109 | ├── lib
110 | └── test
111 |
112 | * Када креирате директиву може бити корисно да се ставе све повезане датотеке са датом директивом (н.п. шаблони, CSS/SASS датотеке, JavaScript) у један директоријум. Ако изаберете овај стил будите козистентни и користите га свуда у вашем пројекту.
113 |
114 | app
115 | └── directives
116 | ├── directive1
117 | │ ├── directive1.html
118 | │ ├── directive1.js
119 | │ └── directive1.sass
120 | └── directive2
121 | ├── directive2.html
122 | ├── directive2.js
123 | └── directive2.sass
124 |
125 | Овај приступ се може комбиновати са обе верзије структуре директоријума.
126 | * Још једна блага варијација на обе структуре директоријума је она коришћена у [ng-boilerplate](http://joshdmiller.github.io/ng-boilerplate/#/home). У њој "unit" тестови за дату компоненту се налазе з истом директоријуму као и сама компонента. На овај начин када направите неку промену у датој компоненти лакше је наћи одговарајуће тестове, тестови такође служе као документација и приказују "uses cases".
127 |
128 | services
129 | ├── cache
130 | │ ├── cache1.js
131 | │ └── cache1.spec.js
132 | └── models
133 | ├── model1.js
134 | └── model1.spec.js
135 |
136 | * Датотека `app.js` садржи дефиницију рута, конфигурацију и/или "manual bootstrap" (уколико је наопходан).
137 | * Свака JavaScript датотека требало би да садржи само једну компоненту. Датотека би требало да буде именована према имену компоненте.
138 | * Користи шаблон структуре Angular пројекта као [Yeoman](http://yeoman.io), [ng-boilerplate](http://joshdmiller.github.io/ng-boilerplate/#/home).
139 |
140 | Ја више преферирам прву структуру јер омогућава лакше пробналажење уобичајених компоненти.
141 |
142 | Конвенције око именовања компоненти се могу наћи у свакој секцији која описује дату компоненту.
143 |
144 | ## Оптимизуј циклус обраде
145 |
146 | * Посматрај само најзначајније промењиве (на пример: када се користи "real-time" комуникације, не позивај петљу обраде у свакој примљеној поруци).
147 | * Прави прорачуне у `$watch` што је могуће једноставнијим. постављање захтевне и споре калкулације у једном `$watch` ће успорити целокупну апликацију ($digest петља се извршава у једној нити из разлога "single-threaded" природе JavaScript-а).
148 |
149 | ## Остало
150 |
151 | * Користи:
152 | * `$timeout` уместо `setTimeout`
153 | * `$window` уместо `window`
154 | * `$document` уместо `document`
155 | * `$http` уместо `$.ajax`
156 |
157 | Ово ће учинити тестирање много лакшим а у неким случајевима и предупредити неочекивано понашање (на пример, ако сте пропустили `$scope.$apply` у `setTimeout`).
158 |
159 | * Аутоматизујте ваш процес рада користећи алате као штоп су:
160 | * [Yeoman](http://yeoman.io)
161 | * [Grunt](http://gruntjs.com)
162 | * [Bower](http://bower.io)
163 |
164 | * Користите "promises" (`$q`) уместо "callbacks". Ово ће учинити да ваш код изгледа елегантније, и сачуваће вас од "callback" пакла.
165 | * Користите `$resource` уместо `$http` кад год је могуће. Виши ниво абстракције спашава вас од непотребног вишка.
166 | * Користите AngularJS "pre-minifier" (like [ngmin](https://github.com/btford/ngmin) или [ng-annotate](https://github.com/olov/ng-annotate)) као превенцију проблема после "minification".
167 | * Не користите глобалне промењиве. Разрешите све зависности користећи "Dependency Injection".
168 | * Не загађујте ваш `$scope`. Додајте смо оне функције или промењиве које се користе унутар датог шаблона.
169 | * Користите контролере уместо `ngInit`.
170 |
171 | #Модули
172 |
173 | Постоје два уобичајена начина да се структуирају модули:
174 |
175 | 0. Према функционалности
176 | 0. Према типу компоненте
177 |
178 | Тренутно нема веће разлике, али први начин изгледа уредније. Такође, ако "lazy-loading" модули су имплементирани (тренутно нису у AngularJS плану развоја), то ће побољшати перформансе апликације.
179 |
180 | #Контролери
181 |
182 | * Немењајте DOM у вашим контролеримаu. Уместо тога користите директиве.
183 | * Именовање контролера се врши према његовој функционалности (на пример: shopping cart, homepage, admin panel) и додатке `Ctrl` на крају имена. Имена контролера су записана у "UpperCamelCase" формату (`HomePageCtrl`, `ShoppingCartCtrl`, `AdminPanelCtrl`, итд.).
184 | * Контролери не би требало да буду дефинисани као глобални (без обзира што AngularJS то дозвољаве, лоша је пракса да се загади глобални "namespace").
185 | * Користи синтаксу низа з дефиницији контролера:
186 |
187 |
188 |
189 | module.controller('MyCtrl', ['dependency1', 'dependency2', ..., 'dependencyn', function (dependency1, dependency2, ..., dependencyn) {
190 | //...body
191 | }]);
192 |
193 |
194 | Коришћење овог типа дефиниција избегава проблеме са "minification". Можете аутоматски генерисати низ дефиниција од једне стандардне користећи алате као што су [ng-annotate](https://github.com/olov/ng-annotate) (и grunt задатак [grunt-ng-annotate](https://github.com/mzgol/grunt-ng-annotate)).
195 | * Користите оригиналне називе зависности контролера. Ово ће вам помоћи да произведете читљивији код:
196 |
197 |
198 |
199 | module.controller('MyCtrl', ['$scope', function (s) {
200 | //...body
201 | }]);
202 |
203 |
204 | је мање читљиво од:
205 |
206 |
207 | module.controller('MyCtrl', ['$scope', function ($scope) {
208 | //...body
209 | }]);
210 |
211 |
212 | Ово је посебно примењиво да датотеку која има толико кода да ћете морати да се вертикално крећете кроз исти. Ово ће највероватније довести до тога да заборавите која је промењива везана за коју зависност.
213 |
214 | * Креирајте што је могуће "тање" контролере. Абстракујте често коришћене функције у сервис.
215 | * комуницирајте унутар различитих контролера коришћењем позивање метода (когуће када деца желе да комуницирају са родитељима) или `$emit`, `$broadcast` i `$on` методе. "Emitted" и "broadcasted" поруке треба држати на минимуму.
216 | * Направите листу свих порука које се преносе коришћењем `$emit`, `$broadcast` и пажљиво их одржавајте из разлога колизије назива и могућих грешака.
217 | * Када је потребно да форматирате податке енкапсулирајте логику форматирања унутар [филтера](#филтери) и декларишите их као зависности:
218 |
219 |
220 | module.filter('myFormat', function () {
221 | return function () {
222 | //body...
223 | };
224 | });
225 |
226 | module.controller('MyCtrl', ['$scope', 'myFormatFilter', function ($scope, myFormatFilter) {
227 | //body...
228 | }]);
229 |
230 | #Директиве
231 |
232 | * Именујте своје директиве користећи "lowerCamelCase"
233 | * Користите `scope` уместо `$scope` у вашој "link" функцији. у "compile", пост/пре "link" функцијама већ сте дефинисали аргументе који це бити прослеђени приликом позива функције, нећете моћи да их промените користећи "DI" (Dependency Injection). Овај стил је такође коришћен унутар AngularJS изворног кода.
234 | * Користите "custom" префиксе за ваше директиве да би спречили колизију имена са туђим бибљотекама.
235 | * Немојте користити `ng` или `ui` префиксе јер су ови резервисани за AngularJS и AngularJS UI употребу.
236 | * DOM манипулације морају бити извршене само кроз директиве.
237 | * Креирајте изоловано подручје када развијате компоненте за вишеструку употребу.
238 |
239 | #Филтери
240 |
241 | * Именујте ваше филтере користећи "lowerCamelCase"
242 | * Креирајте ваше филтере што је могуће "лакшим". Они се зову често током `$digest` петље па креирање спорих филтера ће успорити вашу апликацију.
243 |
244 | #Сервиси
245 |
246 | * Користите "camelCase (lower or upper)" за називе ваших сервиса.
247 | * енкапсулирајте бизнис логику унутар сервиса.
248 | * Сервиси који уоквирују бизнис логику су пожељно `service` уместо `factory`
249 | * За "session-level" кеш можете користити `$cacheFactory`. Ово би требало користити за кеширање резултата захтева или комплексних прорачуна.
250 |
251 | #Шаблони
252 |
253 | * Користите `ng-bind` или `ng-cloak` уместо простог `{{ }}` да би спречили трептање садржаја.
254 | * Избегавајте писање комплексног кода унутар шаблона.
255 | * Када је потребно да динамички поставите `src` слике користите `ng-src` уместо `src` са `{{}}` шаблоном.
256 | * Уместо коришћења "scope" промењиве као текст и користити га заједно са `style` атрибутом са atributom и `{{ }}`, користите директиву `ng-style` са "object-like" параметрима и "scope" промењиве као вредности:
257 |
258 | ...
259 | $scope.divStyle = {
260 | width: 200,
261 | position: 'relative'
262 | };
263 | ...
264 |
265 | my beautifully styled div which will work in IE
;
266 |
267 | #Рутирање
268 |
269 | * Користите `resolve` да разложите све зависности пре него се прикаже "view".
270 |
--------------------------------------------------------------------------------
/README-tr-tr.md:
--------------------------------------------------------------------------------
1 | [](https://gitter.im/mgechev/angularjs-style-guide?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
2 |
3 | # Başlangıç
4 |
5 | Bu dokümanın amacı angular ile geliştirilen ve geçerli olan iyi tasarım ve stillerdir.
6 | En iyi kullanışlar:
7 |
8 | 0. AngularJS kaynak kodu
9 | 0. Kaynak kodları ve okuduğum makaleler
10 | 0. Kendi deneyimlerim
11 |
12 | **Not 1**: Bu stil rehberi hala bir taslak aşamasındadır. Ana amacı tüm kesimlerce kabul edilmesidir.
13 |
14 | **Not 2**: Herhangi bir doküman takip etmeden önce, dokümanın güncel olduğuna dikkat ediniz. Bu doküman en son versiyonu için geçerlidir.
15 |
16 | Bu dokümanda genel Javascript geliştirmelerinin ortak kullanımını göremeyeceksiniz. Genel olarak kullanımlar aşağıdadır:
17 |
18 | 0. [Google's JavaScript dokümanı](https://google.github.io/styleguide/javascriptguide.xml)
19 | 0. [Mozilla's JavaScript dokümanı](https://developer.mozilla.org/en-US/docs/Developer_Guide/Coding_Style)
20 | 0. [Douglas Crockford's JavaScript dokümanı](http://javascript.crockford.com/code.html)
21 | 0. [Airbnb JavaScript dokümanı](https://github.com/airbnb/javascript)
22 |
23 | AngularJs geliştirmeleri için [Google'ın JavaScript dokümanı](https://google.github.io/styleguide/javascriptguide.xml).
24 |
25 | AngularJS Github dokümanı için [ProLoser](https://github.com/ProLoser), [buradan](https://github.com/angular/angular.js/wiki) kontrol edebilirsin.
26 |
27 |
28 | # Tablo içeriği
29 | * [Genel](#genel)
30 | * [Dizin yapısı](#dizin-yapısı)
31 | * [Biçimlendirme](#biçimlendirme)
32 | * [Optimize the digest cycle](#optimize-the-digest-cycle)
33 | * [Diğerleri](#diğerleri)
34 | * [Modüller](#modüller)
35 | * [Kontrolörler](#kontrolörler)
36 | * [Direktifler](#direktifler)
37 | * [Filtreler](#filtreler)
38 | * [Services](#services)
39 | * [Şablonlar](#şablonlar)
40 | * [Yönlendirme](#yönlendirme)
41 | * [i18n](#i18n)
42 | * [Katkı](#katkı)
43 | * [Katkı Sağlayanlar](#katkı-sağlayanlar)
44 |
45 | # Genel
46 |
47 | ## Dizin yapısı
48 |
49 | Büyük AngularJS uygulamaları bir çok bileşenden oluşur. En iyi dizin yapısı dosyalama hiyerarşisidir.
50 | 2 tane ana yaklaşım:
51 |
52 | * Bileşen türü daha öncelikli olacak şekilde bölünmeler ve işlevselliği daha az kullanıma göre yapılandırma.
53 |
54 | Dizin yapısı aşağıdaki şekilde görünecektir:
55 |
56 | ```
57 | .
58 | ├── app
59 | │ ├── app.js
60 | │ ├── controllers
61 | │ │ ├── home
62 | │ │ │ ├── FirstCtrl.js
63 | │ │ │ └── SecondCtrl.js
64 | │ │ └── about
65 | │ │ └── ThirdCtrl.js
66 | │ ├── directives
67 | │ │ ├── home
68 | │ │ │ └── directive1.js
69 | │ │ └── about
70 | │ │ ├── directive2.js
71 | │ │ └── directive3.js
72 | │ ├── filters
73 | │ │ ├── home
74 | │ │ └── about
75 | │ └── services
76 | │ ├── CommonService.js
77 | │ ├── cache
78 | │ │ ├── Cache1.js
79 | │ │ └── Cache2.js
80 | │ └── models
81 | │ ├── Model1.js
82 | │ └── Model2.js
83 | ├── partials
84 | ├── lib
85 | └── test
86 | ```
87 |
88 | * İşlevselliğin ön planda olduğu ve bileşen yapısının daha az yapıda kullanıldığı yapı aşağıdaki gibidir.
89 |
90 | Düzen yapısı:
91 |
92 | ```
93 | .
94 | ├── app
95 | │ ├── app.js
96 | │ ├── common
97 | │ │ ├── controllers
98 | │ │ ├── directives
99 | │ │ ├── filters
100 | │ │ └── services
101 | │ ├── home
102 | │ │ ├── controllers
103 | │ │ │ ├── FirstCtrl.js
104 | │ │ │ └── SecondCtrl.js
105 | │ │ ├── directives
106 | │ │ │ └── directive1.js
107 | │ │ ├── filters
108 | │ │ │ ├── filter1.js
109 | │ │ │ └── filter2.js
110 | │ │ └── services
111 | │ │ ├── service1.js
112 | │ │ └── service2.js
113 | │ └── about
114 | │ ├── controllers
115 | │ │ └── ThirdCtrl.js
116 | │ ├── directives
117 | │ │ ├── directive2.js
118 | │ │ └── directive3.js
119 | │ ├── filters
120 | │ │ └── filter3.js
121 | │ └── services
122 | │ └── service3.js
123 | ├── partials
124 | ├── lib
125 | └── test
126 | ```
127 |
128 | * Dizin yapısı birden çok kelimeden oluşabilir(örn;my-complex-module ),lisp-case sözdizimi kullanın !:
129 |
130 | ```
131 | app
132 | ├── app.js
133 | └── my-complex-module
134 | ├── controllers
135 | ├── directives
136 | ├── filters
137 | └── services
138 | ```
139 |
140 | * Tüm dosyalarınızı verilen yönergelere koyun. (i.e. şablonlar, CSS/SASS dosyaları, JavaScript) tek dosya içerisinde. Eğer böyle bir yaklaşım seçerseniz, proje yaşamı boyunca heryerde bu yaklaşımı kullanabilirsiniz.
141 |
142 | ```
143 | app
144 | └── directives
145 | ├── directive1
146 | │ ├── directive1.html
147 | │ ├── directive1.js
148 | │ └── directive1.sass
149 | └── directive2
150 | ├── directive2.html
151 | ├── directive2.js
152 | └── directive2.sass
153 | ```
154 |
155 | Bu yaklaşım yukarıdaki iki dizin yapısı ile birleştirilmiştir.
156 | * Unit testlerimiz bulunduğu bileşen ile birlikte olmalıdır. Bu yol ile yaptığımız testleri daha kolay buluruz ve yönetimimiz daha kolay olur. Ayrıca testlerimiz dokümantasyon ve kullanıcı senaryolarını da içermelidir.
157 |
158 | ```
159 | services
160 | ├── cache
161 | │ ├── cache1.js
162 | │ └── cache1.spec.js
163 | └── models
164 | ├── model1.js
165 | └── model1.spec.js
166 | ```
167 |
168 | * `app.js` dosyasında yönlendirme bulunmalıdır.
169 | * Her bir JavaScript dosyası sadece **tek bir bileşen** bulundurmalıdır. Dosya bileşenin adı ile adlandırılmış olmalıdır.
170 | * AngularJS proje yapısı şablonu örnek olarak kullanabilirsiniz; [Yeoman](http://yeoman.io), [ng-boilerplate](http://joshdmiller.github.io/ng-boilerplate/#/home).
171 |
172 | Conventions about component naming can be found in each component section.
173 |
174 | ## Biçimlendirme
175 |
176 | [TLDR;](http://developer.yahoo.com/blogs/ydn/high-performance-sites-rule-6-move-scripts-bottom-7200.html) Alltaki komutları koyun.
177 |
178 | ```
179 |
180 |
181 |
182 |
183 | MyApp
184 |
185 |
186 |
189 |
190 |
191 |
192 |
193 | ```
194 |
195 | Basit yapıda tutun ve özelleşmiş direktifleri sonra koyun. Bu yöntem; kodun geliştirmesini ve bakımını daha kolay hale getirir. Ayrıca HTML tarafından daha kolay bulunmasını sağlar.
196 |
197 | ```
198 |
203 | ```
204 |
205 | Diğer HTML niteliklerini [bu dokümanda](http://mdo.github.io/code-guide/#html-attribute-order) bulabilirsiniz.
206 |
207 | ## Optimize the digest cycle
208 |
209 | * Watch only the most vital variables. When required to invoke the `$digest` loop explicitly (it should happen only in exceptional cases), invoke it only when required (for example: when using real-time communication, don't cause a `$digest` loop in each received message).
210 | * For content that is initialized only once and then never changed, use single-time watchers like [`bindonce`](https://github.com/Pasvaz/bindonce) for older versions of AngularJS or one-time bindings in AngularJS >=1.3.0.
211 | * Make the computations in `$watch` as simple as possible. Making heavy and slow computations in a single `$watch` will slow down the whole application (the `$digest` loop is done in a single thread because of the single-threaded nature of JavaScript).
212 | * When watching collections, do not watch them deeply when not strongly required. Better use `$watchCollection`, which performs a shallow check for equility of the result of the watched expression and the previous value of the expression's evaluation.
213 | * Set third parameter in `$timeout` function to false to skip the `$digest` loop when no watched variables are impacted by the invocation of the `$timeout` callback function.
214 | * When dealing with big collections, which change rarely, [use immutable data structures](http://blog.mgechev.com/2015/03/02/immutability-in-angularjs-immutablejs).
215 |
216 | ## Diğerleri
217 |
218 | * Kullan:
219 | * `setTimeout` yerine `$timeout`
220 | * `setInterval` yerine `$interval`
221 | * `window` yerine `$window`
222 | * `$document` yerine `$document`
223 | * `$.ajax` yerine `$http`
224 | * `window.location` veya `$window.location` yerine `$location`
225 | * `document.cookie` yerine `$cookies`
226 |
227 | Böylece kod daha test edilebilir hale gelir ve beklenmeyen hataların önüne geçilir. (Örneğin; unutursan `$scope.$apply` in `setTimeout`).
228 |
229 | * İş akışını bu araçlar ile otomatik hale getirin:
230 | * [Yeoman](http://yeoman.io)
231 | * [Gulp](http://gulpjs.com)
232 | * [Grunt](http://gruntjs.com)
233 | * [Bower](http://bower.io)
234 |
235 | * Callbacks yerine promise yapısını kullanın. (`$q`) Kodu daha güzel, temiz ve test edilebilir hale getirir. Ve bizi callback yapısından kurtarır.
236 | * Mümkün olduğunca `$http` yerine `$resource` kullanın. Soyutlama düzeyinde fazlalılıktan size kurtaracaktır.
237 | * Olası hataları önlemek için AngularJS pre-minifier kullanın. ([ng-annotate](https://github.com/olov/ng-annotate))
238 | * Globals kullanmayın. Tüm bağımlılıkları Dependency Injection ile çözümleyin, bu olası bug çözümleri ve testler için kolaylık sağlayacaktır.
239 | * Kodunuzu `$scope` ile kirletmeyin. Sadece fonksiyon ve değişkenlerde kullanın. Bu kullanılan değişken ve fonksiyonların şablonlarda kullanıldığına dikkat edin.
240 | * Prefer the usage of [controllers instead of `ngInit`](https://github.com/angular/angular.js/pull/4366/files). The only appropriate use of `ngInit` is for aliasing special properties of `ngRepeat`. Besides this case, you should use controllers rather than `ngInit` to initialize values on a scope.
241 | * Değişkenlerde, methodlarda ve özelliklerde `$` ön ekini kullanmayın. Çünkü bu ön ek AngularJS tarafından ayrılmıştır.
242 | * AngularJS DI yapısıyla bağımlılıkları çözerken,bağımlılıkları türlerine göre sıralayınız.AngularJS tarafından ayağa kaldırılan bağımlılıklar ilk sırada olmalı daha sonra sizin yaptığınız bağımlılıklar gelmelidir. Aşağıda bir örnek görebilirsiniz:
243 |
244 | ```javascript
245 | module.factory('Service', function ($rootScope, $timeout, MyCustomDependency1, MyCustomDependency2) {
246 | return {
247 | //Something
248 | };
249 | });
250 | ```
251 |
252 | # Modüller
253 |
254 | * Modül isimleri lowerCamelCase yapısına uygun olmalıdır. Küçük harf ile başlamalıdır. `b` modülü `a` nın bir alt modülü ise, isimlendirme `a.b` şekilde olmalıdır.
255 |
256 | Modülleri yapısına göre 2 şekilde sıralayabiliriz:
257 |
258 | 0. işlevselliğine göre,
259 | 0. bileşen türüne göre.
260 |
261 | Aslında büyük bir fark yok aralarında, ama ilk yöntem daha temiz bir yapıdır. Bunun yanında, eğer lazy-loading modülü gelirse (şuanda AngularJS yol haritasında yok), uygulama performansını artıracaktır.
262 |
263 | # Kontrolörler
264 |
265 | * Kontroller tarafında DOM müdahale etmeyin, bu sizin kontroller tarafındanki test etmenizi zor hale getirir ve bazı prensibleri ihlal etmiş olursunuz [Separation of Concerns principle](https://en.wikipedia.org/wiki/Separation_of_concerns). Bunun yerine directive'leri kullanın.
266 | * Controler'ların ismi yaptığı iş ile aynı isimde olmalıdır. (örneğin; shopping cart, homepage, admin panel) ve sonu `Ctrl` ile bitmelidir. Controler'ların ismi UpperCamelCase (`HomePageCtrl`, `ShoppingCartCtrl`, `AdminPanelCtrl`, vb.) yapısında olmalıdır.
267 | * Controler'lar global olarak tanımlanmamalıdır. (AngularJS buna izin verse bile, bu kötü bir yaklaşımdır ve global isim alanını kirletir. Kullanmayın!).
268 | * Aşağıda tanımlanan örnek yapısında kullanın:
269 |
270 | ```JavaScript
271 | function MyCtrl(dependency1, dependency2, ..., dependencyn) {
272 | // ...
273 | }
274 | module.controller('MyCtrl', MyCtrl);
275 | ```
276 |
277 | In order to prevent problems with minification, you can automatically generate the array definition syntax from the standard one using tools like [ng-annotate](https://github.com/olov/ng-annotate) (and grunt task [grunt-ng-annotate](https://github.com/mzgol/grunt-ng-annotate)).
278 | * If using array definition syntax, use the original names of the controller's dependencies. This will help you produce more readable code:
279 |
280 | ```JavaScript
281 | function MyCtrl(s) {
282 | // ...
283 | }
284 |
285 | module.controller('MyCtrl', ['$scope', MyCtrl]);
286 | ```
287 |
288 | okunabilirliği daha az:
289 |
290 | ```JavaScript
291 | function MyCtrl($scope) {
292 | // ...
293 | }
294 | module.controller('MyCtrl', ['$scope', MyCtrl]);
295 | ```
296 |
297 | This especially applies to a file that has so much code that you'd need to scroll through. This would possibly cause you to forget which variable is tied to which dependency.
298 |
299 | * Make the controllers as lean as possible. Abstract commonly used functions into a service.
300 | * Communicate within different controllers using method invocation (possible when a child wants to communicate with its parent) or `$emit`, `$broadcast` and `$on` methods. The emitted and broadcasted messages should be kept to a minimum.
301 | * Make a list of all messages which are passed using `$emit`, `$broadcast` and manage it carefully because of name collisions and possible bugs.
302 |
303 | Example:
304 |
305 | ```JavaScript
306 | // app.js
307 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
308 | Custom events:
309 | - 'authorization-message' - description of the message
310 | - { user, role, action } - data format
311 | - user - a string, which contains the username
312 | - role - an ID of the role the user has
313 | - action - specific ation the user tries to perform
314 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
315 | ```
316 |
317 | * When you need to format data encapsulate the formatting logic into a [filter](#filters) and declare it as dependency:
318 |
319 | ```JavaScript
320 | function myFormat() {
321 | return function () {
322 | // ...
323 | };
324 | }
325 | module.filter('myFormat', myFormat);
326 |
327 | function MyCtrl($scope, myFormatFilter) {
328 | // ...
329 | }
330 |
331 | module.controller('MyCtrl', MyCtrl);
332 | ```
333 | * In case of nested controllers use "nested scoping" (the `controllerAs` syntax):
334 |
335 | **app.js**
336 | ```javascript
337 | module.config(function ($routeProvider) {
338 | $routeProvider
339 | .when('/route', {
340 | templateUrl: 'partials/template.html',
341 | controller: 'HomeCtrl',
342 | controllerAs: 'home'
343 | });
344 | });
345 | ```
346 | **HomeCtrl**
347 | ```javascript
348 | function HomeCtrl() {
349 | this.bindingValue = 42;
350 | }
351 | ```
352 | **template.html**
353 | ```
354 |
355 | ```
356 |
357 | # Directives
358 |
359 | * Direktif isimleri lowerCamelCase yapısına uygun olmalıdır.
360 | * Link fonksiyonunda `$scope` yerine `scope` kullanın.In the compile, post/pre link functions you have already defined arguments which will be passed when the function is invoked, you won't be able to change them using DI. This style is also used in AngularJS's source code.
361 | * Direktiflerde özel ön ekler kullanın bunun amacı kullandığınız diğer kütüphanelerde isim karışıklığını engeller.Use custom prefixes for your directives to prevent name collisions with third-party libraries.
362 | * Do not use `ng` or `ui` prefixes since they are reserved for AngularJS and AngularJS UI usage.
363 | * DOM manipulations must be done only through directives.
364 | * Create an isolated scope when you develop reusable components.
365 | * Use directives as attributes or elements instead of comments or classes, this will make your code more readable.
366 | * Use `scope.$on('$destroy', fn)` for cleaning up. This is especially useful when you're wrapping third-party plugins as directives.
367 | * Do not forget to use `$sce` when you should deal with untrusted content.
368 |
369 | # Filtreler
370 |
371 | * Filtre isimleri lowerCamelCase yapısına uygun olmalıdır.
372 | * Tüm filtrelerin bağımsız olduğuna emin olun. They are called often during the `$digest` loop so creating a slow filter will slow down your app.
373 | * Filtreleme işlemlerinde sadece bir iş yapın,ve işler tutarlı olsun. More complex manipulations can be achieved by piping existing filters.
374 |
375 | # Services
376 |
377 | Bu bölümde AngularJs Service yapısınına bakıyoruz.Hangisine bağlı olarak geliştirdiğinin önemi yoktur. (i.e. örnek; provider, `.factory`, `.service`).
378 |
379 | * Servis isimleri camelCase yapısına uygun olmalıdır.
380 | * UpperCamelCase (PascalCase) yapısında isimlendirilmelidir, yapıcı fonksiyon örneği kullanılmıştır i.e.:
381 |
382 | ```JavaScript
383 | function MainCtrl($scope, User) {
384 | $scope.user = new User('foo', 42);
385 | }
386 |
387 | module.controller('MainCtrl', MainCtrl);
388 |
389 | function User(name, age) {
390 | this.name = name;
391 | this.age = age;
392 | }
393 |
394 | module.factory('User', function () {
395 | return User;
396 | });
397 | ```
398 |
399 | * Diğer tüm servisler için lowerCamelCase kullanın.
400 |
401 | * Servis katmanınında tüm işlemleri saklayın.
402 | * Services representing the domain preferably a `service` instead of a `factory`. In this way we can take advantage of the "klassical" inheritance easier:
403 |
404 | ```JavaScript
405 | function Human() {
406 | //body
407 | }
408 | Human.prototype.talk = function () {
409 | return "I'm talking";
410 | };
411 |
412 | function Developer() {
413 | //body
414 | }
415 | Developer.prototype = Object.create(Human.prototype);
416 | Developer.prototype.code = function () {
417 | return "I'm coding";
418 | };
419 |
420 | myModule.service('Human', Human);
421 | myModule.service('Developer', Developer);
422 |
423 | ```
424 |
425 | * Session-level önbellekleme yapmak için `$cacheFactory` kullanın.
426 | * Eğer kullandığınız servis yapılandırma gerekiyorsa, servis sağlayıcı kullanın ve bunu `config` callback yapılandırın. Aşağıda bir örnek tanımlanmıştır
427 |
428 | ```JavaScript
429 | angular.module('demo', [])
430 | .config(function ($provide) {
431 | $provide.provider('sample', function () {
432 | var foo = 42;
433 | return {
434 | setFoo: function (f) {
435 | foo = f;
436 | },
437 | $get: function () {
438 | return {
439 | foo: foo
440 | };
441 | }
442 | };
443 | });
444 | });
445 |
446 | var demo = angular.module('demo');
447 |
448 | demo.config(function (sampleProvider) {
449 | sampleProvider.setFoo(41);
450 | });
451 | ```
452 |
453 | # Şablonlar
454 |
455 | * `ng-bind` veya `ng-cloak` kullanın.Instead of simple `{{ }}` to prevent flashing content. //
456 | * Html Şablonları içinde karışık ifadeler yazmaktan kaçının.
457 | * Html Şablonların içinde `src` etiketi yerine AngularJS bize sunmuş olduğu `ng-src` etiketini kullanın.
458 | * Html Şablonların içinde `href` etiketi yerine AngularJS bize sunmuş olduğu `ng-href` etiketini kullanın.
459 | * Scope değişkenlerini string kullanmak yerine `style` özelliği birlikte `{{ }}` kullanın ve direktif olarak `ng-style` kullanın.
460 |
461 | ```HTML
462 |
470 |
471 | my beautifully styled div which will work in IE
;
472 | ```
473 |
474 | # Yönlendirme
475 |
476 | * View gözükmeden önce bağımlılıklarınızı çözmek için `resolve` kullanın.
477 | * `resolve` callback içerisine açık olarak RESTful koymayın.Uygun servislerin içersine birbirden bağımsız olacak şekilde yerleştirin.Böylece önbelleğe izin verme ve separation of concerns principle sağlamış oluruz.
478 |
479 | # i18n
480 |
481 | * Angular yeni versiyonu için (>=1.4.0) i18n araçını kullanın, eğer eski versiyonu kullanıyorsanız (<1.4.0) kullanın [`angular-translate`](https://github.com/angular-translate/angular-translate).
482 |
483 |
484 | # Katkı Sağlayanlar
485 |
486 | [
](https://github.com/mgechev) |[
](https://github.com/pascalockert) |[
](https://github.com/morizotter) |[
](https://github.com/ericguirbal) |[
](https://github.com/mainyaa) |[
](https://github.com/elfinxx) |
487 | :---: |:---: |:---: |:---: |:---: |:---: |
488 | [mgechev](https://github.com/mgechev) |[pascalockert](https://github.com/pascalockert) |[morizotter](https://github.com/morizotter) |[ericguirbal](https://github.com/ericguirbal) |[mainyaa](https://github.com/mainyaa) |[elfinxx](https://github.com/elfinxx) |
489 |
490 | [
](https://github.com/agnislav) |[
](https://github.com/rubystream) |[
](https://github.com/lukaszklis) |[
](https://github.com/susieyy) |[
](https://github.com/cironunes) |[
](https://github.com/cavarzan) |
491 | :---: |:---: |:---: |:---: |:---: |:---: |
492 | [agnislav](https://github.com/agnislav) |[rubystream](https://github.com/rubystream) |[lukaszklis](https://github.com/lukaszklis) |[susieyy](https://github.com/susieyy) |[cironunes](https://github.com/cironunes) |[cavarzan](https://github.com/cavarzan) |
493 |
494 | [
](https://github.com/guiltry) |[
](https://github.com/tornad) |[
](https://github.com/jmblog) |[
](https://github.com/kuzzmi) |[
](https://github.com/dchest) |[
](https://github.com/gsamokovarov) |
495 | :---: |:---: |:---: |:---: |:---: |:---: |
496 | [guiltry](https://github.com/guiltry) |[tornad](https://github.com/tornad) |[jmblog](https://github.com/jmblog) |[kuzzmi](https://github.com/kuzzmi) |[dchest](https://github.com/dchest) |[gsamokovarov](https://github.com/gsamokovarov) |
497 |
498 | [
](https://github.com/clbn) |[
](https://github.com/apetro) |[
](https://github.com/valgreens) |[
](https://github.com/bitdeli-chef) |[
](https://github.com/bradgearon) |[
](https://github.com/astalker) |
499 | :---: |:---: |:---: |:---: |:---: |:---: |
500 | [clbn](https://github.com/clbn) |[apetro](https://github.com/apetro) |[valgreens](https://github.com/valgreens) |[bitdeli-chef](https://github.com/bitdeli-chef) |[bradgearon](https://github.com/bradgearon) |[astalker](https://github.com/astalker) |
501 |
502 | [
](https://github.com/dreame4) |[
](https://github.com/grvcoelho) |[
](https://github.com/bargaorobalo) |[
](https://github.com/hermankan) |[
](https://github.com/jabhishek) |[
](https://github.com/jesselpalmer) |
503 | :---: |:---: |:---: |:---: |:---: |:---: |
504 | [dreame4](https://github.com/dreame4) |[grvcoelho](https://github.com/grvcoelho) |[bargaorobalo](https://github.com/bargaorobalo) |[hermankan](https://github.com/hermankan) |[jabhishek](https://github.com/jabhishek) |[jesselpalmer](https://github.com/jesselpalmer) |
505 |
506 | [
](https://github.com/vorktanamobay) |[
](https://github.com/capaj) |[
](https://github.com/jordanyee) |[
](https://github.com/nacyot) |[
](https://github.com/mariolamacchia) |[
](https://github.com/kirstein) |
507 | :---: |:---: |:---: |:---: |:---: |:---: |
508 | [vorktanamobay](https://github.com/vorktanamobay) |[capaj](https://github.com/capaj) |[jordanyee](https://github.com/jordanyee) |[nacyot](https://github.com/nacyot) |[mariolamacchia](https://github.com/mariolamacchia) |[kirstein](https://github.com/kirstein) |
509 |
510 | [
](https://github.com/mo-gr) |[
](https://github.com/cryptojuice) |[
](https://github.com/olov) |[
](https://github.com/johnnyghost) |[
](https://github.com/sahat) |[
](https://github.com/kaneshin) |
511 | :---: |:---: |:---: |:---: |:---: |:---: |
512 | [mo-gr](https://github.com/mo-gr) |[cryptojuice](https://github.com/cryptojuice) |[olov](https://github.com/olov) |[johnnyghost](https://github.com/johnnyghost) |[sahat](https://github.com/sahat) |[kaneshin](https://github.com/kaneshin) |
513 |
514 | [
](https://github.com/imaimiami) |[
](https://github.com/gitter-badger) |[
](https://github.com/thomastuts) |[
](https://github.com/grapswiz) |[
](https://github.com/coderhaoxin) |[
](https://github.com/ntaoo) |
515 | :---: |:---: |:---: |:---: |:---: |:---: |
516 | [imaimiami](https://github.com/imaimiami) |[gitter-badger](https://github.com/gitter-badger) |[thomastuts](https://github.com/thomastuts) |[grapswiz](https://github.com/grapswiz) |[coderhaoxin](https://github.com/coderhaoxin) |[ntaoo](https://github.com/ntaoo) |
517 |
518 | [
](https://github.com/kuzmeig1) |
519 | :---: |
520 | [kuzmeig1](https://github.com/kuzmeig1) |
521 |
522 | [
](https://github.com/previousdeveloper) |
523 | :---: |
524 | [gokhan](https://github.com/previousdeveloper) |
525 |
--------------------------------------------------------------------------------