Buscar

angular style guide pt br

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 83 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 83 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 83 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Tabela	de	conteúdos
Prefácio
Introdução
Single	Responsability
IIFE
Modules
Controllers
Services
Factories
Data	Services
Directives
Resolving	Promises	for	a	Controller
Manual	Annotating	for	Dependency	Injection
Minification	and	Annotation
Exception	Handling
Naming
Application	Structure	LIFT	Principle
Application	Structure
Modularity
Angular	$	Wrapper	Services
Testing
Animations
Comments
JSHint
Constants
File	Templates	and	Snippets
Angular	Docs
Contributing
License
Angular	Style	Guide	traduzido
2
Guia	de	Estilo	AngularJS
Guia	de	Estilo	opinativo	de	Angular	para	times.	Por	@john_papa
Esse	e-book	foi	idealizado	para	somente	agrupar	as	informações	do	Guia	de	Estilo	para
AngularJS,	feito	pelo	John	Papa.	Ela	foi	traduzida	por:
Lennon	Jesus
Lucas	Moreira
Bruno	Wego
Fonte:	https://github.com/johnpapa/angular-styleguide
Angular	Style	Guide	traduzido
3Prefácio
Guia	de	Estilo	AngularJS
Guia	de	Estilo	opinativo	de	Angular	para	times.	Por	@john_papa
Se	você	procura	por	um	guia	de	estilo	opinativo	para	sintaxe,	convenções	e	estruturação	de
aplicações	AngularJS,	então	siga	em	frente!	Estes	estilos	são	baseados	em	minha
experiência	com	desenvolvimento	com	AngularJS,	apresentações,	cursos	de	treinamento
na	Pluralsight	e	trabalhando	em	equipe.
Se	você	gostar	deste	guia,	confira	meu	curso	Angular	Patterns:	Clean	Code	na
Pluralsight.
A	proposta	deste	guia	de	estilo	é	fornecer	uma	direção	na	construção	de	aplicações	Angular
mostrando	convenções	que	eu	uso,	e	o	mais	importante,	porque	eu	as	escolhi.
A	Importância	da	Comunidade	e	Créditos
Nunca	trabalhe	sozinho.	Acho	que	a	comunidade	Angular	é	um	grupo	incrível,	apaixonado
em	compartilhar	experiências.	Dessa	forma,	Todd	Motto,	um	amigo	e	expert	em	Angular	e
eu	temos	colaborado	com	vários	estilos	e	convenções.	Nós	concordamos	na	maioria	deles,
e	discordamos	em	alguns.	Eu	encorajo	você	a	conferir	o	guia	do	Todd	para	ter	uma	noção
sobre	sua	abordagem	e	como	ela	se	compara	a	esta.
Vários	de	meus	estilos	vieram	de	várias	sessões	de	pair-programming	(programação
pareada)	que	Ward	Bell	e	eu	tivemos.	Embora	não	concordemos	sempre,	meu	amigo	Ward
certamente	me	ajudou	influenciando	na	última	evolução	deste	guia.
Veja	os	estilos	em	um	aplicativo	de	exemplo
Embora	este	guia	explique	o	o	quê,	porque	e	como,	acho	útil	ver	tudo	isso	em	prática.
Este	guia	é	acompanhado	de	uma	aplicação	de	exemplo	que	segue	estes	estilos	e	padrões.
Você	pode	encontrar	a	aplicação	de	exemplo	(chamada	"modular")	aqui	na	pasta		modular	.
Sinta-se	livre	para	pegá-la,	cloná-la	e	forká-la.	Instruções	de	como	rodar	o	aplicativo	estão
em	seu	README.
Angular	Style	Guide	traduzido
4Introdução
Nota	de	tradução:	Os	títulos	originais	de	cada	seção	serão	mantidos,	pois	caso	você
queira	buscar	mais	sobre	estes	assuntos	futuramente,	fazendo	tal	busca	em	inglês
será	obtido	um	resultado	imensamente	melhor.
Após	o	título,	estará	a	tradução	auxiliar,	quando	necessária,	visto	que	alguns	termos
são	mais	facilmente	entendidos	quando	não	traduzidos,	por	fazerem	parte	do	núcleo
do	estudo	em	questão.
Para	eventuais	erros	de	digitação	e/ou	tradução,	favor	enviar	um	pull-request!
Tabela	de	Conteúdo
1.	 Single	Responsibility
2.	 IIFE
3.	 Modules
4.	 Controllers
5.	 Services
6.	 Factories
7.	 Data	Services
8.	 Directives
9.	 Resolving	Promises	for	a	Controller
10.	 Manual	Annotating	for	Dependency	Injection
11.	 Minification	and	Annotation
12.	 Exception	Handling
13.	 Naming
14.	 Application	Structure	LIFT	Principle
15.	 Application	Structure
16.	 Modularity
17.	 Angular	$	Wrapper	Services
18.	 Testing
19.	 Animations
20.	 Comments
21.	 JSHint
22.	 Constants
23.	 File	Templates	and	Snippets
24.	 Angular	Docs
25.	 Contributing
26.	 License
Angular	Style	Guide	traduzido
5Introdução
Single	Responsibility
ou	Responsabilidade	Única
Regra	nº	1
Defina	um	componente	por	arquivo.
O	exemplo	seguinte	define	um	módulo		app		e	suas	dependências,	define	um	controller
e	define	uma	factory,	todos	no	mesmo	arquivo.
/*	evite	*/
angular
				.module('app',	['ngRoute'])
				.controller('SomeController'	,	SomeController)
				.factory('someFactory'	,	someFactory);
function	SomeController()	{	}
function	someFactory()	{	}
Os	mesmos	componentes	agora	estão	separados	em	seus	próprios	arquivos.
/*	recomendado	*/
//	app.module.js
angular
				.module('app',	['ngRoute']);
/*	recomendado	*/
//	someController.js
angular
				.module('app')
				.controller('SomeController'	,	SomeController);
function	SomeController()	{	}
Angular	Style	Guide	traduzido
6Single	Responsability
/*	recomendado	*/
//	someFactory.js
angular
				.module('app')
				.factory('someFactory'	,	someFactory);
function	someFactory()	{	}
De	volta	ao	topo
Angular	Style	Guide	traduzido
7Single	Responsability
IIFE
JavaScript	Closures
Envolva	os	componentes	Angular	em	uma	Immediately	Invoked	Function	Expression
(IIFE	-	Expressão	de	função	imediatamente	invocada).
Por	que?	Uma	IIFE	remove	as	variáveis	do	escopo	global.	Isso	ajuda	a	prevenir
declarações	de	variáveis	e	funções	de	viverem	por	mais	tempo	que	o	esperado	no
escopo	global,	que	também	auxilia	evitar	colisões	de	variáveis.
Por	que?	Quando	seu	código	é	minificado	e	empacotado	dentro	de	um	único	arquivo
para	deployment	no	servidor	de	produção,	você	pode	ter	conflitos	de	variáveis	e	muitas
variáveis	globais.	Uma	IIFE	o	protege	em	todos	estes	aspectos	provendo	escopo	de
variável	para	cada	arquivo.
/*	evite	*/
//	logger.js
angular
		.module('app')
		.factory('logger',	logger);
//	função	logger	é	adicionada	como	uma	variável	global
function	logger()	{	}
//	storage.js
angular
		.module('app')
		.factory('storage',	storage);
//	função	storage	é	adicionada	como	uma	variável	global
function	storage()	{	}
Angular	Style	Guide	traduzido
8IIFE
		/**
			*	recomendado
			*
			*	nada	global	é	deixado	para	trás
			*/
		//	logger.js
		(function()	{
						'use	strict';
						angular
										.module('app')
										.factory('logger',	logger);
						function	logger()	{	}
		})();
		//	storage.js
		(function()	{
						'use	strict';
						angular
										.module('app')
										.factory('storage',	storage);
						function	storage()	{	}
		})();
Nota:	Apenas	para	agilizar,	o	resto	dos	exemplos	neste	guia	omitirão	a	sintaxe	IIFE.
Nota:	IIFE	impede	que	códigos	de	teste	alcancem	membros	privados	como	expressões
regulares	ou	funções	auxiliares	que	são	frequentemente	boas	para	testes	unitários.
Entretanto,	você	pode	testá-las	através	de	membros	acessíveis	ou	expondo-os	pelo
próprio	componente.	Por	exemplo,	colocando	funções	auxiliares,	expressões	regulares
ou	constantes	em	sua	própria	factory	ou	constante.
De	volta	ao	topo
Angular	Style	Guide	traduzido
9IIFE
Modules
ou	Módulos
Avoid	Naming	Collisions
ou	Evitando	Colisão	de	Nomes
Use	uma	única	convenção	de	nomes	com	separadores	para	sub-módulos.
Por	que?	Nomes	únicos	ajudam	a	evitar	colisão	de	nomes	no	módulo.	Separadores
ajudam	a	definir	a	hierarquia	de	módulos	e	submódulos.	Por	exemplo,		app		pode	ser
seu	módulo	raiz,	enquanto		app.dashboard		e		app.users		podem	ser	módulos	que	são
usados	como	dependências	de		app	.
Definições	(aka	Setters)
ps:	aka	é	o	acrônimo	de	Also	Known	As,	de	forma	traduzida,	também	conhecido
como**.
Declare	os	módulos	sem	uma	variável	usando	a	sintaxe	setter.
Por	que?	Com	1	componente	por	arquivo,	raramente	será	necessário	criar	uma
variável	para	o	módulo.
/*	evite	*/
var	app	=	angular.module('app',	[
		'ngAnimate',
		'ngRoute',
		'app.shared',
		'app.dashboard'
]);
Ao	invés,use	a	simples	sintaxe	setter.
/*	recomendado	*/
angular
				.module('app',	[
						'ngAnimate',
						'ngRoute',
						'app.shared',
						'app.dashboard'
		]);
Angular	Style	Guide	traduzido
10Modules
Getters
Ao	usar	um	módulo,	evite	usar	uma	variável.	Em	vez	disso,	use	encadeamento	com	a
sintaxe	getter.
Por	que?	Isso	produz	um	código	mais	legível	e	evita	colisão	de	variáveis	ou
vazamentos.
/*	evite	*/
var	app	=	angular.module('app');
app.controller('SomeController'	,	SomeController);
function	SomeController()	{	}
/*	recomendado	*/
angular
		.module('app')
		.controller('SomeController'	,	SomeController);
function	SomeController()	{	}
Setting	vs	Getting
ou	Definindo	vs	Obtendo
Apenas	set	(configure)	uma	vez	e	get	(receba)	em	todas	as	outras	instâncias.
Por	que?	Um	módulo	deve	ser	criado	somente	uma	vez,	então	recupere-o	deste	ponto
em	diante.
Use		angular.module('app',	[]);		para	definir	(set)	um	módulo.
Use		angular.module('app');		para	pegar	(get)	este	módulo.
Named	vs	Anonymous	Functions
ou	Funções	Nomeadas	vs	Funções	Anônimas
Use	funções	nomeadas	ao	invés	de	passar	uma	função	anônima	como	um	callback.
Por	que?	Isso	produz	um	código	mais	legível,	é	muito	fácil	de	debugar,	e	reduz	a
quantidade	de	callbacks	aninhados	no	código.
Angular	Style	Guide	traduzido
11Modules
/*	evite	*/
angular
		.module('app')
		.controller('Dashboard',	function()	{	});
		.factory('logger',	function()	{	});
/*	recomendado	*/
//	dashboard.js
angular
		.module('app')
		.controller('Dashboard',	Dashboard);
function	Dashboard()	{	}
//	logger.js
angular
		.module('app')
		.factory('logger',	logger);
function	logger()	{	}
De	volta	ao	topo
Angular	Style	Guide	traduzido
12Modules
Controllers
ou	Controladores
controllerAs	View	Syntax
Utilize	a	sintaxe		controllerAs		ao	invés	da	sintaxe		clássica	controller	com	$scope	.
Por	que?	Controllers	são	construídos,	"iniciados",	e	fornecem	um	nova	instância	única,
e	a	sintaxe		controllerAs		é	mais	próxima	de	um	construtor	JavaScript	do	que	a
	sintaxe	clássica	do	$scope	.
Por	que?	Isso	promove	o	uso	do	binding	de	um	objeto	"pontuado",	ou	seja,	com
propriedades	na	View	(ex.		customer.name		ao	invés	de		name	),	que	é	mais	contextual,
legível,	e	evita	qualquer	problema	com	referências	que	podem	ocorrer	sem	a
"pontuação"
Por	que?	Ajuda	a	evitar	o	uso	de	chamadas	ao		$parent		nas	Views	com	controllers
aninhados.
<!--	evite	-->
<div	ng-controller="Customer">
		{{	name	}}
</div>
<!--	recomendado	-->
<div	ng-controller="Customer	as	customer">
	{{	customer.name	}}
</div>
controllerAs	Controller	Syntax
Utilize	a	sintaxe		controllerAs		ao	invés	da	sintaxe		clássica	controller	com	$scope	.
A	sintaxe		controllerAs		usa	o		this		dentro	dos	controllers	que	fica	ligado	ao		$scope	.
Por	que?	O		controllerAs		é	uma	forma	mais	simples	de	lidar	com	o		$scope	.	Você
ainda	poderá	fazer	o	bind	para	a	View	e	ainda	poderá	acessar	os	métodos	do		$scope	.
Por	que?	Ajuda	a	evitar	a	tentação	de	usar	os	métodos	do		$scope		dentro	de	um
controller	quando	seria	melhor	evitá-los	ou	movê-los	para	um	factory.	Considere	utilizar
o		$scope		em	um	factory,	ou	em	um	controller	apenas	quando	necessário.	Por
Angular	Style	Guide	traduzido
13Controllers
exemplo,	quando	publicar	e	subscrever	eventos	usando		$emit	,		$broadcast	,	ou		$on	
considere	mover	estes	casos	para	um	factory	e	invocá-los	a	partir	do	controller.
/*	evite	*/
function	Customer($scope)	{
		$scope.name	=	{};
		$scope.sendMessage	=	function()	{	};
}
/*	recomendado	-	mas	veja	a	próxima	sessão	*/
function	Customer()	{
		this.name	=	{};
		this.sendMessage	=	function()	{	};
}
controllerAs	with	vm
Utilize	uma	variável	de	captura	para	o		this		quando	usar	a	sintaxe		controllerAs	.
Escolha	um	nome	de	variável	consistente	como		vm	,	que	representa	o	ViewModel.
Por	que?	A	palavra-chave		this		é	contextual	e	quando	usada	em	uma	função	dentro
de	um	controller	pode	mudar	seu	contexto.	Capturando	o	contexto	do		this		evita	a
ocorrência	deste	problema.
/*	evite	*/
function	Customer()	{
		this.name	=	{};
		this.sendMessage	=	function()	{	};
}
/*	recomendado	*/
function	Customer()	{
		var	vm	=	this;
		vm.name	=	{};
		vm.sendMessage	=	function()	{	};
}
Nota:	Você	pode	evitar	qualquer	jshint	warnings	colocando	o	comentário	abaixo	acima
da	linha	de	código.
/*	jshint	validthis:	true	*/
var	vm	=	this;
Angular	Style	Guide	traduzido
14Controllers
Nota:	Quando	watches	são	criados	no	controller	utilizando	o		controller	as	,	você	pode
observar	o	objeto		vm.*		utilizando	a	seguinte	sintaxe.	(Crie	watches	com	cuidado	pois
eles	deixam	o	ciclo	de	digest	mais	"carregado".)
$scope.$watch('vm.title',	function(current,	original)	{
		$log.info('vm.title	was	%s',	original);
		$log.info('vm.title	is	now	%s',	current);
});
Bindable	Members	Up	Top
Coloque	os	objetos	que	precisam	de	bind	no	início	do	controller,	em	ordem	alfabética,	e
não	espalhados	através	do	código	do	controller.
Por	que?	Colocar	os	objetos	que	precisam	de	bind	no	início	torna	mais	fácil	de	ler	e	te
ajuda	a	instantaneamente	identificar	quais	objetos	do	controller	podem	ser	utilizados	na
View.
Por	que?	Setar	funções	anônimas	pode	ser	fácil,	mas	quando	essas	funções	possuem
mais	de	1	linha	do	código	elas	podem	dificultar	a	legibilidade.	Definir	as	funções	abaixo
dos	objetos	que	necessitam	de	bind	(as	funções	serão	elevadas	pelo	JavaScript
Hoisting)	move	os	detalhes	de	implementação	para	o	final	do	controller,	mantém	os
objetos	que	necessitam	de	bind	no	topo,	e	deixa	o	código	mais	fácil	de	se	ler.
/*	evite	*/
function	Sessions()	{
		var	vm	=	this;
		vm.gotoSession	=	function()	{
				/*	...	*/
		};
		vm.refresh	=	function()	{
				/*	...	*/
		};
		vm.search	=	function()	{
				/*	...	*/
		};
		vm.sessions	=	[];
		vm.title	=	'Sessions';
Angular	Style	Guide	traduzido
15Controllers
/*	recomendado	*/
function	Sessions()	{
		var	vm	=	this;
		vm.gotoSession	=	gotoSession;
		vm.refresh	=	refresh;
		vm.search	=	search;
		vm.sessions	=	[];
		vm.title	=	'Sessions';
		////////////
		function	gotoSession()	{
				/*	*/
		}
		function	refresh()	{
				/*	*/
		}
		function	search()	{
				/*	*/
		}
Angular	Style	Guide	traduzido
16Controllers
Nota:	Se	a	função	possuir	apenas	1	linha	considere	mantê-la	no	topo,	desde	que	a
legibilidade	não	seja	afetada.
/*	evite	*/
function	Sessions(data)	{
		var	vm	=	this;
		vm.gotoSession	=	gotoSession;
		vm.refresh	=	function()	{
						/**
							*	linhas
							*	de
							*	código
							*	afetam
							*	a
							*	legibilidade
							*/
		};
		vm.search	=	search;
		vm.sessions	=	[];
		vm.title	=	'Sessions';
/*	recomendado	*/
function	Sessions(dataservice)	{
		var	vm	=	this;
		vm.gotoSession	=	gotoSession;
		vm.refresh	=	dataservice.refresh;	//	1	linha	está	OK
		vm.search	=	search;
		vm.sessions	=	[];
		vm.title	=	'Sessions';
Function	Declarations	to	Hide	Implementation	Details
Utilize	declarações	de	funções	para	esconder	detalhes	de	implementação.	Mantenha
seus	objetos	que	necessitam	de	bind	no	topo.	Quando	você	precisar	fazer	o	bind	de
uma	função	no	controller,	aponte	ela	para	a	declaração	de	função	que	aparece	no	final
do	arquivo.	Ela	está	ligada	diretamente	aos	objetos	que	precisam	de	bind	no	início	do
arquivo.	Para	mais	detalhes	veja	este	post.
Por	que?	Colocar	os	objetos	que	precisam	de	bind	no	início	torna	mais	fácil	de	ler	e	te
ajuda	a	instantaneamente	identificar	quais	objetos	do	controller	podem	ser	utilizados	na
View.	(Mesmo	do	item	anterior.)
Angular	Style	Guide	traduzido
17Controllers
Por	que?	Colocar	os	detalhes	de	implementação	de	uma	função	no	final	do	arquivo
coloca	a	complexidade	fora	do	foco,	logo,	você	pode	focar	nas	coisas	importantes	no
topo.
Por	que?	Declarações	de	funçõessão	içadas,	logo,	não	existe	problema	de	se	utilizar
uma	função	antes	dela	ser	definida	(como	haveria	com	expressões	de	função).
Por	que?	Você	nunca	precisará	se	preocupar	com	declarações	de	funções	quebrarem
seu	código	por	colocar		var	a		antes	de		var	b		por	que		a		depende	de		b	.
Por	que?	A	ordenação	é	crítica	em	expressões	de	função.
/**
*	evite
*	Usar	expressões	de	funções.
*/
function	Avengers(dataservice,	logger)	{
		var	vm	=	this;
		vm.avengers	=	[];
		vm.title	=	'Avengers';
		var	activate	=	function()	{
						return	getAvengers().then(function()	{
										logger.info('Activated	Avengers	View');
						});
		}
		var	getAvengers	=	function()	{
						return	dataservice.getAvengers().then(function(data)	{
										vm.avengers	=	data;
										return	vm.avengers;
						});
		}
		vm.getAvengers	=	getAvengers;
		activate();
}
Note-se	que	as	coisas	importantes	estão	espalhadas	no	exemplo	anterior.	No	exemplo
abaixo,	nota-se	que	as	coisas	importantes	do	javascript	estão	logo	no	topo.	Por
exemplo,	os	objetos	que	precisam	de	bind	no	controller	como		vm.avengers		e
	vm.title	.	Os	detalhes	de	implementação	estão	abaixo.	Isto	é	mais	fácil	de	ler.
Angular	Style	Guide	traduzido
18Controllers
/*
*	recomendado
*	Usar	declarações	de	funções
*	e	objetos	que	precisam	de	bind	no	topo.
*/
function	Avengers(dataservice,	logger)	{
		var	vm	=	this;
		vm.avengers	=	[];
		vm.getAvengers	=	getAvengers;
		vm.title	=	'Avengers';
		activate();
		function	activate()	{
						return	getAvengers().then(function()	{
										logger.info('Activated	Avengers	View');
						});
		}
		function	getAvengers()	{
						return	dataservice.getAvengers().then(function(data)	{
										vm.avengers	=	data;
										return	vm.avengers;
						});
		}
}
Defer	Controller	Logic
Remova	a	lógica	do	controller	delegando	ela	a	services	e	factories.
Por	que?	A	lógica	pode	ser	reutilizada	em	múltiplos	controllers	quando	colocada	em
um	service	e	exposta	através	de	uma	função.
Por	que?	A	lógica	em	um	serviço	pode	ser	mais	facilmente	isolada	em	um	teste
unitário,	enquanto	a	lógica	feita	no	controlador	pode	ser	facilmente	mockada.
Por	que?	Remove	as	dependências	e	esconde	os	detalhes	de	implementação	do
controlador.
Angular	Style	Guide	traduzido
19Controllers
/*	evite	*/
function	Order($http,	$q)	{
		var	vm	=	this;
		vm.checkCredit	=	checkCredit;
		vm.total	=	0;
		function	checkCredit()	{
						var	orderTotal	=	vm.total;
						return	$http.get('api/creditcheck').then(function(data)	{
										var	remaining	=	data.remaining;
										return	$q.when(!!(remaining	>	orderTotal));
						});
		};
}
/*	recomendado	*/
function	Order(creditService)	{
		var	vm	=	this;
		vm.checkCredit	=	checkCredit;
		vm.total	=	0;
		function	checkCredit()	{
					return	creditService.check();
		};
}
Keep	Controllers	Focused
Defina	um	controller	para	a	view	e	tente	não	reutilizar	o	controller	para	outras	views.	Ao
invés	disso,	coloque	as	lógicas	reaproveitáveis	em	factories	e	mantenha	o	controller
simples	e	focado	em	sua	view.
Por	que?	Reutilizar	controllers	em	várias	views	é	arriscado	e	um	boa	cobertura	de
testes	end	to	end	(e2e)	é	obrigatório	para	se	garantir	estabilidade	em	grandes
aplicações.
Assigning	Controllers
Quando	um	controller	deve	ser	pareado	com	sua	view	e	algum	componente	pode	ser
reutilizado	por	outros	controllers	ou	views,	defina	controllers	juntamente	de	suas	rotas.
Nota:	Se	uma	View	é	carregada	de	outra	forma	que	não	seja	através	de	uma	rota,
então	utilize	a	sintaxe		ng-controller="Avengers	as	vm"	.
Angular	Style	Guide	traduzido
20Controllers
Por	que?	Parear	os	controllers	nas	rotas	permite	diferentes	rotas	invocarem	diferentes
pares	de	controllers	e	views.	Quando	um	controller	é	utilizado	na	view	usando	a	sintaxe
	ng-controller	,	esta	view	sempre	será	associada	ao	mesmo	controller.
/*	evite	-	quando	utilizar	com	uma	rota	e	emparelhamento	dinâmico	é	desejado	*/
//	route-config.js
angular
		.module('app')
		.config(config);
function	config($routeProvider)	{
		$routeProvider
						.when('/avengers',	{
								templateUrl:	'avengers.html'
						});
}
<!--	avengers.html	-->
<div	ng-controller="Avengers	as	vm">
</div>
/*	recomendado	*/
//	route-config.js
angular
		.module('app')
		.config(config);
function	config($routeProvider)	{
		$routeProvider
						.when('/avengers',	{
										templateUrl:	'avengers.html',
										controller:	'Avengers',
										controllerAs:	'vm'
						});
}
<!--	avengers.html	-->
<div>
</div>
De	volta	ao	topo
Angular	Style	Guide	traduzido
21Controllers
Services
ou	Serviços
Singletons
Services	são	instanciados	com	a	palavra-chave		new	,	use		this		para	métodos
públicos	e	variáveis.	Services	são	bastante	similares	a	factories,	use	um	factory	para
consistência.
Nota:	Todos	services	em	Angular	são	singletons.	Isso	significa	que	há	apenas	uma
instância	do	serviço	para	cada	injetor.
//	service
angular
		.module('app')
		.service('logger',	logger);
function	logger()	{
this.logError	=	function(msg)	{
		/*	*/
};
}
//	factory
angular
		.module('app')
		.factory('logger',	logger);
function	logger()	{
		return	{
						logError:	function(msg)	{
								/*	*/
						}
	};
}
De	volta	ao	topo
Angular	Style	Guide	traduzido
22Services
Factories
ou	Fábricas
Single	Responsibility
ou	Responsabilidade	Única
Factories	devem	ter	responsabilidade	única,	que	é	encapsulado	pelo	seu	contexto.
Assim	que	uma	factory	começa	a	exceder	a	proposta	de	singularidade,	uma	nova
factory	deve	ser	criada.
Singletons
Factories	são	singletons	e	retornam	um	objeto	que	contém	os	membros	do	serviço.
Nota:	Todos	services	em	Angular	são	singletons.
Accessible	Members	Up	Top
ou	Membros	acessíveis	no	topo
Exponha	os	membros	que	podem	ser	invocados	no	serviço	(a	interface)	no	topo,
utilizando	uma	técnica	derivada	do	Revealing	Module	Pattern.
Por	que?	Colocando	no	topo	os	membros	que	podem	ser	invocados	da	factory,	a
leitura	torna-se	mais	fácil	e	ajuda	a	identificar	imediatamente	quais	membros	da	factory
podem	ser	invocados	e	testados	através	de	teste	unitário	(e/ou	mock).
Por	que?	É	especialmente	útil	quando	o	arquivo	torna-se	muito	longo	e	ajuda	a	evitar	a
necessidade	de	rolagem	para	ver	o	que	é	exposto.
Por	que?	Definir	as	funções	conforme	você	escreve	o	código	pode	ser	fácil,	mas
quando	essas	funções	tem	mais	que	1	linha	de	código,	elas	podem	reduzir	a	leitura	e
causar	rolagem.	Definir	a	interface	no	topo	do	que	pode	ser	invocado	da	factory,	torna	a
leitura	mais	fácil	e	mantém	os	detalhes	de	implementação	mais	abaixo.
Angular	Style	Guide	traduzido
23Factories
/*	evite	*/
function	dataService()	{
var	someValue	=	'';
function	save()	{
		/*	*/
};
function	validate()	{
		/*	*/
};
return	{
				save:	save,
				someValue:	someValue,
				validate:	validate
};
}
/*	recomendado	*/
function	dataService()	{
		var	someValue	=	'';
		var	service	=	{
						save:	save,
						someValue:	someValue,
						validate:	validate
		};
		return	service;
		////////////
		function	save()	{
						/*	*/
		};
		function	validate()	{
						/*	*/
		};
}
Dessa	forma,	os	bindings	são	espelhados	através	do	objeto	da	interface	da	factory	e	os
valores	primitivos	não	podem	ser	atualizados	sozinhos	utilizando	o	revealing	module
pattern
Angular	Style	Guide	traduzido
24Factories
Function	Declarations	to	Hide	Implementation	Details
ou	Declarações	de	função	para	esconder	detalhes	de	implementação
Use	function	declarations	(declarações	de	função)	para	esconder	detalhes	de
implementação.	Mantenha	os	membros	acessíveis	da	factory	no	topo.	Aponte	as
function	declarations	que	aparecem	posteriormente	no	arquivo.	Para	mais	detalhes	leia
esse	post.
Por	que?	Colocando	os	membros	acessíveisno	topo,	a	leitura	torna-se	mais	fácil	e
ajuda	a	identificar	imediatamente	quais	membros	da	factory	podem	ser	acessados
externamente.
Por	que?	Colocando	os	detalhes	de	implementação	da	função	posteriormente	no
arquivo	move	a	complexidade	para	fora	da	visão,	permitindo	que	você	veja	as	coisas
mais	importantes	no	topo.
Angular	Style	Guide	traduzido
25Factories
Por	que?	Function	declarations	(declarações	de	função)	são	içadas	(hoisted)	para	que
não	hajam	preocupações	em	utilizar	uma	função	antes	que	ela	seja	definida	(como
haveria	com	function	expressions	(expressões	de	função)).
Por	que?	Você	nunca	deve	se	preocupar	com	function	declaration	(declarações	de
função)	onde		var	a		está	antes	de		var	b		vai	ou	não	quebrar	o	seu	código	porque		a	
depende	de		b	.
Por	que?	A	ordem	é	crítica	com	function	expressions	(expressões	de	função)
/**
*	evite
*	Utilizando	function	expressions	(expressões	de	função)
*/
function	dataservice($http,	$location,	$q,	exception,	logger)	{
		var	isPrimed	=	false;
		var	primePromise;
		var	getAvengers	=	function()	{
					//	detalhes	de	implementação
		};
		var	getAvengerCount	=	function()	{
						//	detalhes	de	implementação
		};
		var	getAvengersCast	=	function()	{
					//	detalhes	de	implementação
		};
		var	prime	=	function()	{
					//	detalhes	de	implementação
		};
		var	ready	=	function(nextPromises)	{
						//	detalhes	de	implementação
		};
		var	service	=	{
						getAvengersCast:	getAvengersCast,
						getAvengerCount:	getAvengerCount,
						getAvengers:	getAvengers,
						ready:	ready
		};
		return	service;
}
Angular	Style	Guide	traduzido
26Factories
/**
*	recomendado
*	Utilizando	function	declarations	(declarações	de	função)
*	e	membros	acessíveis	no	topo.
*/
function	dataservice($http,	$location,	$q,	exception,	logger)	{
		var	isPrimed	=	false;
		var	primePromise;
		var	service	=	{
						getAvengersCast:	getAvengersCast,
						getAvengerCount:	getAvengerCount,
						getAvengers:	getAvengers,
						ready:	ready
		};
		return	service;
		////////////
		function	getAvengers()	{
					//	detalhes	de	implementação
		}
		function	getAvengerCount()	{
						//	detalhes	de	implementação
		}
		function	getAvengersCast()	{
					//	detalhes	de	implementação
		}
		function	prime()	{
						//	detalhes	de	implementação
		}
		function	ready(nextPromises)	{
						//	detalhes	de	implementação
		}
}
De	volta	ao	topo
Angular	Style	Guide	traduzido
27Factories
Data	Services
ou	Serviços	de	dados
Separate	Data	Calls
ou	Chamadas	de	dados	separadas
A	lógica	de	refatoração	(refactor)	para	operações	com	dados	e	interação	com	dados	na
factory.	Faça	serviços	de	dados	responsáveis	por	chamadas	XHR,	armazenamento
local	(local	storage),	armazenamento	em	memória	(stashing)	ou	outras	operações	com
dados.
Por	que?	A	responsabilidade	dos	controladores	(controllers)	é	para	a	apresentação	e
coleta	de	informações	da	view.	Eles	não	devem	se	importar	como	os	dados	são
adquiridos,	somente	como	"perguntar"	por	eles.	Separar	os	serviços	de	dados	(data
services),	move	a	lógica	de	como	adquiri-los	para	o	serviço	e	deixa	o	controlador
(controller)	mais	simples	e	focado	na	view.
Por	que?	Isso	torna	mais	fácil	testar	(mock	ou	real)	as	chamadas	de	dados	quando
estiver	testando	um	controlador	(controller)	que	utiliza	um	serviço	de	dados	(data
service).
Por	que?	A	implementação	de	um	serviço	de	dados	(data	service)	pode	ter	um	código
bem	específico	para	lidar	com	o	repositório	de	dados.	Isso	pode	incluir	cabeçalhos
(headers),	como	comunicar	com	os	dados	ou	outros	serviços,	como	$http.	Separando	a
lógica	de	dados	em	um	serviço,	coloca	toda	a	lógica	somente	em	um	local	e	esconde	a
implementação	de	consumidores	de	fora	(talvez	um	controlador	(controller)),	tornado
mais	fácil	mudar	a	implementação.
Angular	Style	Guide	traduzido
28Data	Services
/*	recomendado	*/
//	factory	de	serviço	de	dados	(data	service	factory)
angular
		.module('app.core')
		.factory('dataservice',	dataservice);
dataservice.$inject	=	['$http',	'logger'];
function	dataservice($http,	logger)	{
		return	{
						getAvengers:	getAvengers
		};
		function	getAvengers()	{
						return	$http.get('/api/maa')
										.then(getAvengersComplete)
										.catch(getAvengersFailed);
						function	getAvengersComplete(response)	{
										return	response.data.results;
						}
						function	getAvengersFailed(error)	{
										logger.error('XHR	Failed	for	getAvengers.'	+	error.data);
						}
		}
}
Nota:	O	serviço	de	dados	(data	service)	é	chamado	pelos	consumidores,	como	um
controlador	(controller),	escondendo	a	implementação	dos	consumidores,	como
mostrado	abaixo.
Angular	Style	Guide	traduzido
29Data	Services
/*	recomendado	*/
//	controlador	chamando	uma	factory	de	serviço	de	dados
angular
		.module('app.avengers')
		.controller('Avengers',	Avengers);
Avengers.$inject	=	['dataservice',	'logger'];
function	Avengers(dataservice,	logger)	{
		var	vm	=	this;
		vm.avengers	=	[];
		activate();
		function	activate()	{
						return	getAvengers().then(function()	{
										logger.info('Activated	Avengers	View');
						});
		}
		function	getAvengers()	{
						return	dataservice.getAvengers()
										.then(function(data)	{
														vm.avengers	=	data;
														return	vm.avengers;
										});
		}
}
Return	a	Promise	from	Data	Calls
ou	Retorne	uma	promessa	de	chamadas	de	dados
Quando	chamar	um	serviço	de	dados	(data	service)	que	retorna	uma	promessa
(promise),	como	o	$http,	retorne	uma	promessa	(promise)	na	função	que	está
chamando	também.
Por	que?	Você	pode	encandear	as	promessas	(promises)	juntas	e	definir	ações	após	a
promessa	(promise)	da	chamada	do	dado	ser	completada,	resolvendo	ou	rejeitando	a
promessa	(promise).
Angular	Style	Guide	traduzido
30Data	Services
/*	recomendado	*/
activate();
function	activate()	{
		/**
			*	Passo	1
			*	Chame	a	função	getAvengers	para	os	dados
			*	dos	vingadores	(avengers)	e	espere	pela	promessa	(promise)
			*/
		return	getAvengers().then(function()	{
						/**
							*	Passo	4
							*	Faça	uma	ação	resolvendo	a	promessa	(promise)	finalizada
							*/
						logger.info('Activated	Avengers	View');
		});
}
function	getAvengers()	{
				/**
					*	Passo	2
					*	Chame	o	serviço	de	dados	(data	service)	e	espere
					*	pela	promessa	(promise)
					*/
				return	dataservice.getAvengers()
								.then(function(data)	{
												/**
													*	Passo	3
													*	Atribua	os	dados	e	resolva	a	promessa	(promise)
													*/
												vm.avengers	=	data;
												return	vm.avengers;
				});
}
De	volta	ao	topo
Angular	Style	Guide	traduzido
31Data	Services
Directives
ou	Diretivas
Limit	1	Per	File
ou	Limite	1	por	arquivo
Crie	uma	diretiva	(directive)	por	arquivo.	Nomeie	o	arquivo	pela	diretiva.
Por	que?	É	fácil	misturar	todas	as	diretivas	em	um	arquivo,	mas	é	difícil	depois	separá-
las,	já	que	algumas	são	compartilhadas	entre	aplicativos,	outras	pelos	módulos
(modules)	e	algumas	somente	para	um	módulo.
Por	que?	Uma	diretiva	(directive)	por	arquivo	é	mais	fácil	de	dar	manutenção.
```javascript	/	evite	/	/	directives.js	/
angular	.module('app.widgets')
/	diretiva	de	pedido	(order)	que	é	específica	para	o	módulo	de	pedido	/
.directive('orderCalendarRange',	orderCalendarRange)
/	diretiva	de	vendas	(sales)	que	pode	ser	usada	em	qualquer	lugar	do	aplicativo	de
vendas	/	.directive('salesCustomerInfo',	salesCustomerInfo)
/	diretiva	de	spinner	que	pode	ser	usada	em	qualquer	lugar	dos	aplicativos	/
.directive('sharedSpinner',	sharedSpinner);
		function	orderCalendarRange()	{
						/*	detalhes	de	implementação	*/
		}
		function	salesCustomerInfo()	{
						/*	detalhes	de	implementação	*/
		}
		function	sharedSpinner()	{/*	detalhes	de	implementação	*/
		}
Angular	Style	Guide	traduzido
32Directives
		```javascript
		/*	recomendado	*/
		/*	calendarRange.directive.js	*/
		/**
			*	@desc	diretiva	de	pedido	(order)	que	é	específica	para	o	módulo	de	pedido	em	uma	companhia	chamada	Acme
			*	@example	<div	acme-order-calendar-range></div>
			*/
		angular
						.module('sales.order')
						.directive('acmeOrderCalendarRange',	orderCalendarRange);
		function	orderCalendarRange()	{
						/*	detalhes	de	implementação	*/
		}
		/*	recomendado	*/
		/*	customerInfo.directive.js	*/
		/**
			*	@desc	diretiva	de	spinner	que	pode	ser	usada	em	qualquer	lugar	de	um	aplicativo	de	vendas	em	uma	companhia	chamada	Acme
			*	@example	<div	acme-sales-customer-info></div>
			*/
		angular
						.module('sales.widgets')
						.directive('acmeSalesCustomerInfo',	salesCustomerInfo);
		function	salesCustomerInfo()	{
						/*	detalhes	de	implementação	*/
		}
		/*	recomendado	*/
		/*	spinner.directive.js	*/
		/**
			*	@desc	diretiva	de	spinner	que	pode	ser	usada	em	qualquer	lugar	de	aplicativo	em	uma	companhia	chamada	Acme
			*	@example	<div	acme-shared-spinner></div>
			*/
		angular
						.module('shared.widgets')
						.directive('acmeSharedSpinner',	sharedSpinner);
		function	sharedSpinner()	{
						/*	detalhes	de	implementação	*/
		}
Angular	Style	Guide	traduzido
33Directives
Nota:	Há	diferentes	opções	de	nomear	diretivas	(directives),	especialmente	quando	elas	podem	ser	usadas	em	escopos	(scopes)	variados.	Escolha	uma	que	faça	a	diretiva	e	o	nome	do	arquivo	distinto	e	simples.	Alguns	exemplos	são	mostrados	abaixo,	mas	veja	a	seção	de	nomeação	para	mais	recomendações.
Limit	DOM	Manipulation
ou	Limite	a	manipulação	do	DOM
Quando	estiver	manipulando	o	DOM	diretamente,	utilize	uma	diretiva	(directive).	Se
formas	alternativas	podem	ser	utilizadas,	como:	utilizar	CSS	para	setar	estilos	ou
serviços	de	animação	(animation	services),	Angular	templating,		ngShow		ou		ngHide	,
então	prefira	utilizá-los.	Por	exemplo,	se	uma	diretiva	simplesmente	esconde	ou	mostra
um	elemento,	use	ngHide/ngShow.
Por	que?	A	manipulação	do	DOM	pode	ser	difícil	de	testar,	debugar,	e	há	melhores
maneiras	(ex:	CSS,	animações	(animations),	templates).
Provide	a	Unique	Directive	Prefix
ou	Forneça	um	prefixo	único	para	as	diretivas
Forneça	um	curto,	único	e	descritivo	prefixo	para	a	diretiva,	como
	acmeSalesCustomerInfo	,	que	é	declarado	no	HTML	como		acme-sales-customer-info	.
Por	que?	Um	prefixo	curto	e	único	identifica	o	contexto	e	a	origem	da	diretiva.	Por
exemplo,	o	prefixo		cc-		pode	indicar	que	a	diretiva	é	parte	de	um	aplicativo	da
CodeCamper,	enquanto	a	diretiva		acme-		pode	indicar	uma	diretiva	para	a	companhia
Acme.
Nota:	Evite		ng-	,	pois	são	reservadas	para	as	diretivas	do	AngularJS.	Pesquise
largamente	as	diretivas	utilizadas	para	evitar	conflitos	de	nomes,	como		ion-		que	são
utilizadas	para	o	Ionic	Framework.
Restrict	to	Elements	and	Attributes
ou	Restringir	para	elementos	e	atributos
Quando	criar	uma	diretiva	que	faça	sentido	por	si	só	como	um	elemento,	utilize
restrição		E		(elemento	personalizado)	e	opcionalmente		A		(atributo	personalizado).
Geralmente,	se	ela	pode	ter	o	seu	próprio	controlador	(controller),		E		é	o	apropriado.
Em	linhas	gerais,		EA		é	permitido,	mas	atente	para	a	implementação	como	elemento
quando	faz	sentido	por	si	só	e	como	atributo	quando	estende	algo	existente	no	DOM.
Por	que?	Faz	sentido.
Angular	Style	Guide	traduzido
34Directives
Por	que?	Nós	podemos	utilizar	uma	diretiva	como	uma	classe	(class),	mas	se	a
diretiva	está	realmente	agindo	como	um	elemento,	faz	mais	sentido	utilizar	como	um
elemento,	ou	pelo	menos	como	um	atributo.
Nota:	EA	é	o	padrão	para	o	Angular	1.3	+
<!--	evite	-->
<div	class="my-calendar-range"></div>
/*	evite	*/
angular
		.module('app.widgets')
		.directive('myCalendarRange',	myCalendarRange);
function	myCalendarRange()	{
		var	directive	=	{
						link:	link,
						templateUrl:	'/template/is/located/here.html',
						restrict:	'C'
		};
		return	directive;
		function	link(scope,	element,	attrs)	{
				/*	*/
		}
}
<!--	recomendado	-->
<my-calendar-range></my-calendar-range>
<div	my-calendar-range></div>
Angular	Style	Guide	traduzido
35Directives
/*	recomendado	*/
angular
		.module('app.widgets')
		.directive('myCalendarRange',	myCalendarRange);
function	myCalendarRange()	{
		var	directive	=	{
						link:	link,
						templateUrl:	'/template/is/located/here.html',
						restrict:	'EA'
		};
		return	directive;
		function	link(scope,	element,	attrs)	{
				/*	*/
		}
}
Directives	and	ControllerAs
ou	Diretivas	e	"ControladorComo"
Utilize	a	sintaxe		controller	as		com	uma	diretiva	para	consistência	com	o	uso	de
	controller	as		com	os	pares	view	e	controlador	(controller).
Por	que?	Faz	sentido	e	não	é	difícil.
Nota:	A	diretiva	(directive)	abaixo	demonstra	algumas	maneiras	que	você	pode	utilizar
escopos	(scopes)	dentro	de	link	e	controller	de	uma	diretiva,	utilizando	controllerAs.	Eu
coloquei	o	template	somente	para	manter	tudo	em	um	mesmo	local.
<div	my-example	max="77"></div>
Angular	Style	Guide	traduzido
36Directives
angular
		.module('app')
		.directive('myExample',	myExample);
function	myExample()	{
		var	directive	=	{
						restrict:	'EA',
						templateUrl:	'app/feature/example.directive.html',
						scope:	{
										max:	'='
						},
						link:	linkFunc,
						controller	:	ExampleController,
						controllerAs:	'vm'
		};
		return	directive;
		ExampleController.$inject	=	['$scope'];
		function	ExampleController($scope)	{
						//	Injetando	$scope	somente	para	comparação
						/*	jshint	validthis:true	*/
						var	vm	=	this;
						vm.min	=	3;
						vm.max	=	$scope.max;
						console.log('CTRL:	$scope.max	=	%i',	$scope.max);
						console.log('CTRL:	vm.min	=	%i',	vm.min);
						console.log('CTRL:	vm.max	=	%i',	vm.max);
		}
		function	linkFunc(scope,	el,	attr,	ctrl)	{
						console.log('LINK:	scope.max	=	%i',	scope.max);
						console.log('LINK:	scope.vm.min	=	%i',	scope.vm.min);
						console.log('LINK:	scope.vm.max	=	%i',	scope.vm.max);
		}
}
<!--	example.directive.html	-->
<div>hello	world</div>
<div>max=<input	ng-model="vm.max"/></div>
<div>min=<input	ng-model="vm.min"/></div>
De	volta	ao	topo
Angular	Style	Guide	traduzido
37Directives
Resolving	Promises	for	a	Controller
ou	Resolvendo	promessas	para	um	controlador
Controller	Activation	Promises
ou	Ativação	de	promessas	no	controlador
Resolva	a	lógica	de	inicialização	no	controlador	(controller)	em	uma	função		iniciar	.
Por	que?	Colocando	a	lógica	de	inicialização	em	um	lugar	consistente	no	controlador
(controller),	torna	mais	fácil	de	localizar,	mais	consistente	para	testar	e	ajuda	a	evitar	o
espalhamento	da	lógica	de	inicialização	pelo	controlador	(controller).
Nota:	Se	você	precisa	cancelar	a	rota	condicionalmente	antes	de	utilizar	o	controlador
(controller),	utilize	uma	resolução	de	rota	(route	resolve).
/*	evite	*/
function	Avengers(dataservice)	{
		var	vm	=	this;
		vm.avengers	=	[];
		vm.title	=	'Avengers';
		dataservice.getAvengers().then(function(data)	{
						vm.avengers	=	data;
						return	vm.avengers;
		});
}
Angular	Style	Guide	traduzido
38Resolving	Promises	for	a	Controller
/*	recomendado	*/
function	Avengers(dataservice)	{
		var	vm	=	this;
		vm.avengers	=	[];
		vm.title	=	'Avengers';
		iniciar();
		////////////
		function	iniciar()	{
						return	dataservice.getAvengers().then(function(data)	{
										vm.avengers	=	data;
										return	vm.avengers;
						});
		}
}
Route	Resolve	Promises
ou	Resolução	de	promessas	na	rota
Quando	o	controlador	(controller)	depende	de	uma	promessa	ser	resolvida,	resolva	as
dependências	no		$routeProvider		antes	da	lógica	do	controlador	(controller)ser
executada.	Se	você	precisa	cancelar	a	rota	condicionalmente	antes	do	controlador
(controller)	ser	ativado,	utilize	uma	resolução	de	rota	(route	resolve).
Por	que?	Um	controlador	(controller)	pode	precisar	de	dados	antes	de	ser	carregado.
Esses	dados	podem	vir	de	uma	promessa	(promise)	através	de	uma	factory
personalizada	ou	$http.	Utilizar	resolução	de	rota	(route	resolve)	permite	as	promessas
(promises)	serem	resolvidas	antes	da	lógica	do	controlador	(controller)	ser	executada,
então	ele	pode	executar	ações	através	dos	dados	dessa	promessa	(promise).
/*	evite	*/
angular
		.module('app')
		.controller('Avengers',	Avengers);
function	Avengers(movieService)	{
		var	vm	=	this;
		//	não	resolvida
		vm.movies;
		//	resolvida	assíncrona
		movieService.getMovies().then(function(response)	{
						vm.movies	=	response.movies;
		});
}
Angular	Style	Guide	traduzido
39Resolving	Promises	for	a	Controller
/*	melhor	*/
//	route-config.js
angular
		.module('app')
		.config(config);
function	config($routeProvider)	{
		$routeProvider
						.when('/avengers',	{
										templateUrl:	'avengers.html',
										controller:	'Avengers',
										controllerAs:	'vm',
										resolve:	{
														moviesPrepService:	function(movieService)	{
																		return	movieService.getMovies();
														}
										}
						});
}
//	avengers.js
angular
		.module('app')
		.controller('Avengers',	Avengers);
Avengers.$inject	=	['moviesPrepService'];
function	Avengers(moviesPrepService)	{
				/*	jshint	validthis:true	*/
				var	vm	=	this;
				vm.movies	=	moviesPrepService.movies;
}
Nota:	As	dependências	no	código	de	exemplos	do		movieService		não	estão	seguras
para	minificação.	Para	mais	detalhes	de	como	fazer	o	código	seguro	para	minificação,
veja	as	seções	injeção	de	dependência	(dependency	injection)	e	minificação	e
anotação	(minification	and	annotation).
De	volta	ao	topo
Angular	Style	Guide	traduzido
40Resolving	Promises	for	a	Controller
Manual	Annotating	for	Dependency	Injection
ou	Anotação	Manual	para	Injeção	de	Dependência
UnSafe	for	Minification
ou	Não	seguro	para	Minificação
Evite	usar	o	atalho	de	sintaxe	de	declarar	dependências	sem	usar	uma	abordagem
segura	para	minificação.
Por	que?	Os	parâmetros	do	componente	(por	ex.	controller,	factory,	etc)	serão
convertidos	em	variáveis	encurtadas.	Por	exemplo,		common		e		dataservice		podem
virar		a		ou		b		e	não	serem	encontrados	pelo	AngularJS.
/*	evite	-	não	seguro	para	minificação*/
angular
				.module('app')
				.controller('Dashboard',	Dashboard);
function	Dashboard(common,	dataservice)	{
}
Este	código	pode	produzir	variáveis	encurtadas	quando	minificado	e,	assim,	causar
erro	em	tempo	de	execução.
/*	evite	-	não	seguro	para	minificação*/
angular.module('app').controller('Dashboard',	d);function	d(a,	b)	{	}
Manually	Identify	Dependencies
ou	Identifique	Dependências	Manualmente
Use		$inject		para	identificar	manualmente	suas	dependências	de	componentes	do
AngularJS.
Por	que?	Esta	técnica	espelha	a	técnica	usada	por		ng-annotate	,	a	qual	eu	recomendo
para	automatizar	a	criação	de	dependências	seguras	para	minificação.	Se		ng-
annotate		detectar	que	a	injeção	já	foi	feita,	ela	não	será	duplicada.
Angular	Style	Guide	traduzido
41Manual	Annotating	for	Dependency	Injection
Por	que?	Isto	salvaguarda	suas	dependências	de	serem	vulneráveis	a	problemas	de
minificação	quando	parâmetros	podem	ser	encurtados.	Por	exemplo,		common		e
	dataservice		podem	se	tornar		a		ou		b		e	não	serem	encontrados	pelo	AngularJS.
Por	que?	Evite	criar	dependências	in-line	pois	listas	longas	podem	ser	difíceis	de	ler	no
array.	Além	disso,	pode	ser	confuso	o	array	ser	uma	série	de	strings	enquanto	o	último
item	é	a	função	do	componente.
/*	evite	*/
angular
				.module('app')
				.controller('Dashboard',
								['$location',	'$routeParams',	'common',	'dataservice',
												function	Dashboard($location,	$routeParams,	common,	dataservice)	{}
								]);
/*	evite	*/
angular
		.module('app')
		.controller('Dashboard',
					['$location',	'$routeParams',	'common',	'dataservice',	Dashboard]);
function	Dashboard($location,	$routeParams,	common,	dataservice)	{
}
/*	recomendado	*/
angular
				.module('app')
				.controller('Dashboard',	Dashboard);
Dashboard.$inject	=	['$location',	'$routeParams',	'common',	'dataservice'];
function	Dashboard($location,	$routeParams,	common,	dataservice)	{
}
Nota:	Quando	sua	função	estiver	abaixo	de	um	return	o	$inject	pode	ficar	inacessível
(isso	pode	acontecer	em	uma	diretiva).	Você	pode	resolver	isso	movendo	o	$inject	para
acima	do	return	ou	usando	a	sintaxe	alternativa	de	injeção	de	array.
Nota:		ng-annotate	0.10.0		introduziu	um	comportamento	em	que	ele	move	o		$inject	
para	onde	ele	possa	ser	acessado.
Angular	Style	Guide	traduzido
42Manual	Annotating	for	Dependency	Injection
//	dentro	da	definição	de	diretiva
function	outer()	{
				return	{
								controller:	DashboardPanel,
				};
				DashboardPanel.$inject	=	['logger'];	//	inacessível
				function	DashboardPanel(logger)	{
				}
}
//	dentro	da	definição	de	diretiva
function	outer()	{
				DashboardPanel.$inject	=	['logger'];	//	acessível
				return	{
								controller:	DashboardPanel,
				};
				function	DashboardPanel(logger)	{
				}
}
Manually	Identify	Route	Resolver	Dependencies
ou	Identifique	Dependências	do	Resolvedor	de	Rotas	Manualmente
Use	$inject	para	identificar	manualmente	as	dependências	do	seu	resolvedor	de	rotas
para	componentes	do	AngularJS.
Por	que?	Esta	técnica	separa	a	função	anônima	do	resolvedor	de	rota,	tornando-a
mais	fácil	de	ler.
Por	que?	Uma	chamada	a		$inject		pode	facilmente	preceder	o	resolvedor	para	fazer
qualquer	dependência	segura	para	minificação.
Angular	Style	Guide	traduzido
43Manual	Annotating	for	Dependency	Injection
/*	recomendado	*/
function	config($routeProvider)	{
				$routeProvider
								.when('/avengers',	{
												templateUrl:	'avengers.html',
												controller:	'Avengers',
												controllerAs:	'vm',
												resolve:	{
																moviesPrepService:	moviePrepService
												}
								});
}
moviePrepService.$inject	=		['movieService'];
function	moviePrepService(movieService)	{
				return	movieService.getMovies();
}
De	volta	ao	topo
Angular	Style	Guide	traduzido
44Manual	Annotating	for	Dependency	Injection
Minification	and	Annotation
ou	Minificação	e	Anotação
ng-annotate
Use	ng-annotate	para	Gulp	ou	Grunt	e	comente	as	funções	que	precisam	de	injeção	de
dependência	automatizada	usando		/**	@ngInject	*/	
Por	que?	Isso	protege	seu	código	de	qualquer	dependência	que	pode	não	estar
usando	práticas	seguras	para	minificação.
Por	que?		ng-min		está	deprecated.
Eu	prefiro	Gulp	pois	sinto	que	é	mais	fácil	de	escrever,	de	ler,	e	de	debugar.
O	código	a	seguir	não	está	usando	dependências	seguras	para	minificação.
angular
				.module('app')
				.controller('Avengers',	Avengers);
/*	@ngInject	*/
function	Avengers(storageService,	avengerService)	{
				var	vm	=	this;
				vm.heroSearch	=	'';
				vm.storeHero	=	storeHero;
				function	storeHero(){
								var	hero	=	avengerService.find(vm.heroSearch);
								storageService.save(hero.name,	hero);
				}
}
Quando	o	código	acima	é	executado	através	de	ng-annotate	produzirá	a	seguinte	saída
com	a	anotação		$inject		e	se	tornará	seguro	para	minificação.
Angular	Style	Guide	traduzido
45Minification	and	Annotation
angular
				.module('app')
				.controller('Avengers',	Avengers);
/*	@ngInject	*/
function	Avengers(storageService,	avengerService)	{
				var	vm	=	this;
				vm.heroSearch	=	'';
				vm.storeHero	=	storeHero;
				function	storeHero(){
								var	hero	=	avengerService.find(vm.heroSearch);
								storageService.save(hero.name,hero);
				}
}
Avengers.$inject	=	['storageService',	'avengerService'];
Nota:	Se		ng-annotate		detectar	que	a	injeção	já	foi	feita	(por	ex.		@ngInject		foi
detectado),	o	código	do		$inject		não	será	duplicado.
Nota:	Quando	usar	um	resolvedor	de	rotas	você	pode	prefixar	a	função	do	resolvedor
com		/*	@ngInject	*/		o	que	produzirá	código	devidamente	anotado,	mantendo
qualquer	dependência	injetada	segura	para	minificação.
//	Usando	anotação	@ngInject
function	config($routeProvider)	{
				$routeProvider
								.when('/avengers',	{
												templateUrl:	'avengers.html',
												controller:	'Avengers',
												controllerAs:	'vm',
												resolve:	{	/*	@ngInject	*/
																moviesPrepService:	function(movieService)	{
																				return	movieService.getMovies();
																}
												}
								});
}
Nota:	A	partir	do	Angular	1.3	use	o	parâmetro		ngStrictDi		da	diretiva		ngApp	.
Quando	presente,	o	injetor	será	criado	no	modo	"strict-di"	fazendo	com	que	a
aplicação	falhe	ao	tentar	invocar	funções	que	não	usem	anotação	explícita	de
função	(elas	podem	não	ser	seguras	para	minificação).	Informação	de	debug	será
logada	no	console	para	ajudar	a	rastrear	o	código	ofensivo.		<body	ng-app="APP"
ng-strict-di>	
Angular	Style	Guide	traduzido
46Minification	and	Annotation
Utilize	Gulp	ou	Grunt	para	o	ng-annotate
Utilize	gulp-ng-annotate	ou	grunt-ng-annotate	para	tarefas	de	build	automatizadas.
Injete		/*	@ngInject	*/		antes	de	qualquer	função	que	tenha	dependências.
Por	que?	ng-annotate	vai	capturar	todas	as	dependências,	mas	as	vezes	requer	dicas
utilizando	a	sintaxe		/*	@ngInject	*/		.
O	código	abaixo	é	um	exemplo	de	uma	task	Gulp	utilizando	ngAnnotate
gulp.task('js',	['jshint'],	function()	{
				var	source	=	pkg.paths.js;
				return	gulp.src(source)
								.pipe(sourcemaps.init())
								.pipe(concat('all.min.js',	{newLine:	';'}))
								//	Annotate	before	uglify	so	the	code	get's	min'd	properly.
								.pipe(ngAnnotate({
												//	true	helps	add	where	@ngInject	is	not	used.	It	infers.
												//	Doesn't	work	with	resolve,	so	we	must	be	explicit	there
												add:	true
								}))
								.pipe(bytediff.start())
								.pipe(uglify({mangle:	true}))
								.pipe(bytediff.stop())
								.pipe(sourcemaps.write('./'))
								.pipe(gulp.dest(pkg.paths.dev));
});
De	volta	ao	topo
Angular	Style	Guide	traduzido
47Minification	and	Annotation
Exception	Handling
ou	Tratamento	de	exceção
decorators
ou	decoradores
Utilize	um	decorator,	no	seu	config	utilizando	o	serviço		$provide	,	no	serviço
	$exceptionHandler		para	realizar	ações	customizadas	quando	um	erro	ocorrer.
Por	que?	Fornece	um	caminho	consistente	para	manipular	erros	não	tratados	pelo
Angular	em	tempo	de	desenvolvimento	ou	execução	(run-time).
Nota:	Outra	opção	é	sobrescrever	o	serviço	ao	invés	de	utilizar	um	decorator.	Esta	é
uma	boa	opção,	mas	se	você	quer	manter	o	comportamento	padrão	e	estender,	o
decorator	é	recomendado.
Angular	Style	Guide	traduzido
48Exception	Handling
/*	recomendado	*/
angular
				.module('blocks.exception')
				.config(exceptionConfig);
exceptionConfig.$inject	=	['$provide'];
function	exceptionConfig($provide)	{
				$provide.decorator('$exceptionHandler',	extendExceptionHandler);
}
extendExceptionHandler.$inject	=	['$delegate',	'toastr'];
function	extendExceptionHandler($delegate,	toastr)	{
				return	function(exception,	cause)	{
								$delegate(exception,	cause);
								var	errorData	=	{
												exception:	exception,
												cause:	cause
								};
								/**
									*	Pode	adicionar	o	erro	para	um	serviço	de	coleções,
									*	adicionar	os	erros	no	$rootScope,	logar	os	erros	em	um	servidor	remoto
									*	ou	logar	localmente.	Ou	lançar	a	exceção.	Isso	cabe	interiamente	à	você.
									*	throw	exception;
									*/
								toastr.error(exception.msg,	errorData);
				};
}
Exception	Catchers
ou	Coletores	de	exceção
Criar	um	factory	que	expõe	uma	interface	para	capturar	e	tratar	adequadamente	as
exceções.
Por	que?	Fornece	uma	forma	consistente	de	coletar	exceções	que	podem	ser
lançadas	no	seu	código	(ex.	durante	uma	chamada	XHR	ou	uma	promessa	(promise)
que	falhou).
Nota:	O	coletor	de	exceção	é	bom	para	coletar	e	reagir	às	exceções	específicas	das
chamadas	que	você	sabe	que	podem	ser	lançadas.	Por	exemplo,	quando	realizar	uma
chamada	XHR	que	retorna	dados	de	um	serviço	remoto	e	você	quer	coletar	qualquer
exceção	desse	serviço,	reagindo	de	uma	maneira	única.
Angular	Style	Guide	traduzido
49Exception	Handling
/*	recomendado	*/
angular
				.module('blocks.exception')
				.factory('exception',	exception);
exception.$inject	=	['logger'];
function	exception(logger)	{
				var	service	=	{
								catcher:	catcher
				};
				return	service;
				function	catcher(message)	{
								return	function(reason)	{
												logger.error(message,	reason);
								};
				}
}
Route	Errors
Gerencie	e	log	todos	os	erros	de	routing	utilizando	o		$routeChangeError	.
Por	que?	Fornece	uma	maneira	consistente	de	gerenciar	erros	relacionados	a	routing.
Por	que?	Potencialmente	fornece	uma	melhor	experiência	de	usuário	se	um	erro	de
routing	ocorrer	e	você	redirecionar	o	usuário	para	uma	tela	amigável	com	mais	detalhes
ou	opções	de	recuperação.
Angular	Style	Guide	traduzido
50Exception	Handling
/*	recomendado	*/
function	handleRoutingErrors()	{
				/**
					*	Cancelamento	de	rota:
					*	Quando	houver	erro	no	roteamento,	vá	para	o	dashboard.
					*	Forneça	uma	cláusula	de	saída	se	ele	tentar	fazer	isso	2	vezes.
					*/
				$rootScope.$on('$routeChangeError',
								function(event,	current,	previous,	rejection)	{
												var	destination	=	(current	&&	(current.title	||	current.name	||	current.loadedTemplateUrl))	||
																'unknown	target';
												var	msg	=	'Error	routing	to	'	+	destination	+	'.	'	+	(rejection.msg	||	''
												/**
													*	Opcionalmente	log	usando	um	serviço	customizado	ou	$log.
													*	(Não	se	esqueça	de	injetar	o	serviço	customizado)
													*/
												logger.warning(msg,	[current]);
								}
				);
}
De	volta	ao	topo
Angular	Style	Guide	traduzido
51Exception	Handling
Naming
ou	Nomenclatura
Diretrizes	de	Nomenclatura
Use	nomes	consistentes	para	todos	os	componentes	seguindo	um	padrão	que
descreva	a	funcionalidade	do	componente	e	(opcionalmente)	seu	tipo.	Meu	padrão
recomendado	é		característica.tipo.js	.	Existem	dois	nomes	para	a	maioria	dos
componentes:
o	nome	do	arquivo	(	avengers.controllers.js	)
o	nome	de	componente	registrado	pelo	Angular	(	AvengersController	)
Por	que?	As	convenções	de	nomenclatura	ajudam	a	fornecer	uma	maneira	consistente
de	encontrar	algo	à	primeira	vista.	Consistência	dentro	do	projeto	é	vital.	Consistência
dentro	de	um	time	é	importante.	Consistência	em	toda	a	empresa	proporciona	uma
enorme	eficiência.
Por	que?	As	convenções	de	nomenclatura	deveriam	simplesmente	te	ajudar	a
encontrar	trechos	do	seu	código	mais	rápido	e	torná-lo	mais	fácil	de	se	entender.
Feature	File	Names
ou	Nome	para	funcionalidades
Use	nomes	consistentes	para	todos	os	componentes	seguindo	um	padrão	que
descreve	a	funcionalidade	do	componente	e,	em	seguida,	(opcionalmente)	o	seu	tipo.
Meu	padrão	recomendado	é		feature.type.js	.
Por	que?	Fornece	uma	maneira	consistente	para	identificar	componentes	mais
rapidamente.
Por	que?	Fornece	um	padrão	apropriado	pra	qualquer	tarefa	automatizada.
Angular	Style	Guide	traduzido
52Naming
/**
	*	opções	comuns
	*/
//	Controllers
avengers.js
avengers.controller.js
avengersController.js
//	Services/Factories
logger.js
logger.service.js
loggerService.js
/**
	*	recomendado
	*/
//	controllers
avengers.controller.js
avengers.controller.spec.js//	services/factories
logger.service.js
logger.service.spec.js
//	constants
constants.js
//	module	definition
avengers.module.js
//	routes
avengers.routes.js
avengers.routes.spec.js
//	configuration
avengers.config.js
//	directives
avenger-profile.directive.js
avenger-profile.directive.spec.js
Nota:	Outra	convenção	comum	é	nomear	arquivos	dos	controllers	sem	a	palavra
	controller		no	nome	do	arquivo	como	avengers.js		em	vez	de
	avengers.controller.js	.	Todas	as	outras	convenções	ainda	mantêm	o	uso	de	um
Angular	Style	Guide	traduzido
53Naming
sufixo	do	tipo.	Controllers	são	o	tipo	mais	comum	de	componente,	portanto	isso	só
economiza	digitação	e	ainda	é	facilmente	identificável.	Eu	recomendo	que	você	escolha
uma	convenção	que	seja	mais	coerente	para	sua	equipe.
/**
	*	recomendado
	*/
//	Controllers
avengers.js
avengers.spec.js
Test	File	Names
ou	Nome	para	aquivos	de	testes
Nomeie	as	especificações	de	testes	de	forma	similar	aos	componentes	que	elas
testam,	com	o	sufixo		spec	.
Por	que?	Fornece	um	modo	consistente	para	identificar	rapidamente	os	componentes.
Por	que?	Fornece	padrões	de	correspondência	para	o	karma	ou	outros	test	runners.
/**
	*	recomendado
	*/
avengers.controller.spec.js
logger.service.spec.js
avengers.routes.spec.js
avenger-profile.directive.spec.js
Controller	Names
ou	Nomes	para	controller
Use	nomes	consistentes	para	todos	os	controllers	nomeados	após	as	sua
funcionalidade.	Use	UpperCamelCase	para	os	controllers,	assim	como	para	seus
construtores.
Por	que?	Fornece	um	modo	consistente	para	identificar	e	referenciar	os	controllers.
Por	que?	O	UpperCamelCase	é	o	modo	mais	comum	para	identificar	objetos	que
serão	instanciados	através	de	construtores.
Angular	Style	Guide	traduzido
54Naming
/**
	*	recomendado
	*/
//	avengers.controller.js
angular
				.module
				.controller('HeroAvengers',	HeroAvengers);
function	HeroAvengers(){	}
Controller	Name	Suffix
ou	sufixo	"Controllers"
Complemente	o	nome	do	controller	com	ou	sem	o	sufixo		Controller	.	Escolha	uma
opção,	não	ambas.
Por	que?	O	sufixo		Controller		é	mais	usado	e	mais	descritivo.
/**
	*	recomendado:	Opção	1
	*/
//	avengers.controller.js
angular
				.module
				.controller('Avengers',	Avengers);
function	Avengers(){	}
/**
	*	recomendado:	Opção	2
	*/
//	avengers.controller.js
angular
				.module
				.controller('AvengersController',	AvengersController);
function	AvengersController(){	}
Factory	Names
ou	Nomes	para	factory
Angular	Style	Guide	traduzido
55Naming
Use	nomes	consistentes	para	todas	as	factories	nomeadas	após	sua	funcionalidade.
Use	a	conveção	camelCase	para	services	e	factories.	Evite	prefixos	com		$	.
Por	que?	Fornece	um	modo	consistente	de	identificar	e	referenciar	rapidamente	as
factories.
Por	que?	Evite	colisão	de	nomes	com	factories	e	services	pré-programados	que	usam
o	prefixo		$	.
/**
	*	recomendado
	*/
//	logger.service.js
angular
				.module
				.factory('logger',	logger);
function	logger(){	}
Directive	Component	Names
ou	Nomes	para	directive
Use	nomes	consistentes	para	todas	as	directives	usando	a	convenção	camelCase.	Use
um	prefixo	curto	para	descrever	a	área	a	qual	a	directive	pertence	(como	prefixo	da
compania	ou	do	projeto).
Por	que?	Fornece	um	modo	consistente	de	identificar	e	referenciar	rapidamente	os
componentes.
/**
	*	recomendado
	*/
//	avenger.profile.directive.js
angular
				.module
				.directive('xxAvengerProfile',	xxAvengerProfile);
//	usage	is	<xx-avenger-profile>	</xx-avenger-profile>
function	xxAvengerProfile(){	}
Modules
Angular	Style	Guide	traduzido
56Naming
ou	Módulos
Quando	há	vários	módulos,	o	arquivo	principal	deste	módulo	é	nomeado
	app.module.js	,	enquanto	os	módulos	dependentes	são	nomeados	de	acordo	com	o
que	eles	representam.	Por	exemplo,	um	módulo	admin	é	nomeado		admin.module.js	.
Os	nomes	dos	respectivos	módulos	registrados	seriam		app		e		admin	.
Por	que?	Fornece	consistência	para	múltiplos	módulos,	e	para	expansão	para	grandes
aplicações.
Por	que?	Fornece	um	modo	fácil	para	automação	de	tarefas,	a	fim	de	carregar	todos
as	definições	dos	módulos	em	primeiro	lugar,	então	os	demais	arquivos
(empacotamento).
Configuration
ou	Configuração
Separe	a	configuração	do	módulo	em	seu	próprio	arquivo,	nomeado	após	o	módulo.
Um	arquivo	de	configuração	para	o	módulo	principal		app		é	nomeado		app.config.js	
(ou	simplesmente		config.js	).	Uma	configuração	para	o	módulo		admin.module.js		é
nomeada		admin.config.js	.
Por	que?	Separa	a	configuração	do	módulo	da	definição,	dos	componentes	e	do
código	ativo.
Por	que?	Fornece	um	local	identificável	para	definir	as	configurações	de	um	módulo.
Routes
ou	Rotas
Separe	as	configurações	das	rotas	em	seus	próprios	arquivos.	Os	exemplos	podem	ser
	app.route.js		para	o	módulo	princial,	e		admin.route.js		para	o	módulo		admin	.	Mesmo
nas	menores	aplicações,	prefiro	esta	separação	das	demais	configurações.	Uma
alternativa	é	um	nome	mais	longo,	como		admin.config.route.js	.
De	volta	ao	topo
Angular	Style	Guide	traduzido
57Naming
Application	Structure	LIFT	Principle
ou	Princípio	da	estrutura	LIFT	na	aplicação
LIFT
Estruture	a	sua	aplicação	de	um	modo	onde	você	possa:		L	ocate	(Localizar)	seu
código	rapidamente,		I	dentify	(Identificar)	o	código	facilmente,	manter	a	estrutura	a
mais		F	lattest	(Plana)	que	você	conseguir,	e		T	ry	(Tentar)	seguir	o	conceito	de	DRY
(Don't	Repeat	Yourself	-	Não	repita	a	si	mesmo).	A	estrutura	deve	seguir	essas	4	regras
básicas.
Por	que	LIFT?:	Fornece	uma	estrutura	consistente	que	escala	bem,	é	modular,	e	torna
mais	fácil	para	aumentar	a	eficiência	ao	desenvolver,	pois	encontra-se	o	código
rapidamente.	Outra	forma	de	verificar	a	estrutura	da	sua	aplicação	é	se	perguntar:
Quão	rápido	é	para	você	abrir	e	trabalhar	em	todos	os	arquivos	relacionados	com	uma
funcionalidade?
Quando	estou	sentindo	que	não	estou	confortável	com	a	minha	estrutura,	eu	volto	e
revisito	as	regras	do	LIFT
1.	 	L	ocating	(Localizar)	nosso	código	é	fácil
2.	 	I	dentify	(Identificar)	o	código	rapidamente
3.	 	F	lat	(Plano)	-	Deixar	a	estrutura	a	mais	plana	que	conseguirmos
4.	 	T	ry	(Tentar)	se	manter	DRY	(Don’t	Repeat	Yourself	-	Não	repita	a	si	mesmo)	ou
T-DRY
Locate
ou	Localizar
Torne	a	localização	do	seu	código:	intuitiva,	simples	e	rápida.
Por	que?	Acho	que	isso	é	super	importante	para	um	projeto.	Se	a	equipe	não	pode
encontrar	rapidamente	os	arquivos	que	precisam	para	trabalhar,	eles	não	serão
capazes	de	trabalhar	da	forma	mais	eficiente	possível,	e	a	estrutura	precisa	mudar.
Você	pode	não	saber	o	nome	do	arquivo	ou	onde	os	arquivos	relacionados	estão,	por
isso,	colocando-os	nos	locais	mais	intuitivos	e	próximos	uns	dos	outros,	economiza
uma	boa	parcela	de	tempo.	Uma	pasta	descrevendo	a	estrutura	pode	ajudá-lo.
Angular	Style	Guide	traduzido
58Application	Structure	LIFT	Principle
/bower_components
/client
		/app
				/avengers
				/blocks
						/exception
						/logger
				/core
				/dashboard
				/data
				/layout
				/widgets
		/content
		index.html
.bower.json
Identify
ou	Identificar
Quando	você	olhar	para	um	arquivo,	prontamente	você	deve	saber	o	que	ele	contém	e
o	que	representa.
Por	que?	Você	gasta	menos	tempo	caçando	e	procurando	por	código,	e	torna-se	mais
eficiente.	Se	isso	significa	nomes	de	arquivos	mais	longos,	então	que	assim	seja.	Seja
descritivo	nos	nomes	de	arquivos	e	mantenha	o	conteúdo	do	arquivo	somente	com	1
componente.	Evite	arquivos	com	vários	controladores	(controllers),	múltiplos	serviços
(services),	ou	uma	mistura.	Existem	exceções	de	1	regra	por	arquivo	quando	eu	tenho
um	conjunto	de	recursos	muito	pequenos	que	estão	todos	relacionados	uns	aos	outros,
eles	ainda	são	facilmente	identificáveis.
Flat
ou	Plano
Mantenha	uma	estrutura	planade	pastas	o	máximo	que	for	possível.	Quando	você	tiver
7	arquivos	ou	mais,	comece	a	considerar	separá-los.
Por	que?	Ninguém	quer	pesquisar	7	níveis	de	pastas	para	encontrar	um	arquivo.
Pense	sobre	menus	em	web	sites	-	nada	mais	profundo	do	que	2	níveis	deve	ser
levado	a	sério.	Em	uma	estrutura	de	pastas	não	há	nenhum	número	mágico,	mas
quando	uma	pasta	tem	7-10	arquivos,	pode	ser	a	hora	de	criar	subpastas.	Baseie-se	no
seu	nível	de	conforto.	Use	uma	estrutura	mais	plana	até	que	haja	um	valor	óbvio	(para
ajudar	o	resto	do	LIFT)	na	criação	de	uma	nova	pasta.
Angular	Style	Guide	traduzido
59Application	Structure	LIFT	Principle
T-DRY	(Try	to	Stick	to	DRY)
ou	Tente	manter-se	em	DRY	-	Não	repita	a	si	mesmo
Mantenha-se	DRY,	mas	não	fique	louco	e	sacrifique	a	legibilidade.
Por	que?	Não	ficar	se	repetindo	é	importante,	mas	não	é	crucial	se	acabar	sacrificando
os	outros	itens	do	LIFT,	por	isso	eu	chamo	de	T-DRY	(Tente	não	ficar	se	repetindo).	Eu
não	quero	escrever	session-view.html	para	uma	view,	porque	obviamente	é	uma	view.
Se	não	é	óbvio	ou	uma	convenção,	então	eu	renomeio.
De	volta	ao	topo
Angular	Style	Guide	traduzido
60Application	Structure	LIFT	Principle
Application	Structure
ou	Estrutura	da	aplicação
Overall	Guidelines
ou	Orientações	gerais
Tenha	uma	visão	de	curto	prazo	da	implementação	e	uma	visão	de	longo	prazo.	Em
outras	palavras,	comece	pequeno,	mas	tenha	em	mente	o	caminho	que	o	aplicativo
pode	tomar.	Todo	o	código	do	aplicativo	vai	em	uma	pasta	raiz	chamada		app	.	Todo	o
conteúdo	é	feito	com	um	recurso	por	arquivo.	Cada	controlador	(controller),	serviço
(service),	módulo	(module),	visão	(view)	está	em	seu	próprio	arquivo.	Todos	os	scripts
de	terceiros	são	armazenados	em	uma	outra	pasta	raiz	e	não	na	pasta		app	.	Não	fui
eu	quem	escreveu	esses	scripts,	então	eu	não	quero	que	eles	baguncem	meu
aplicativo	(	bower_components	,	scripts	,		lib	).
Nota:	Encontre	mais	detalhes	sobre	essa	estrutura	em	esse	post	original	sobre	a
estrutura	da	aplicação.
Layout
Coloque	os	componentes	que	definem	o	layout	geral	do	aplicativo	em	uma	pasta
chamada		layout	.	Eles	podem	incluir	uma	view	e	um	controller	que	agem	como
recipiente	para	o	app,	navegação,	menus,	áreas	de	conteúdo,	e	outras	regiões.
Por	que?	Organiza	todos	os	layouts	em	um	único	lugar	reutilizado	em	toda	a
aplicação.
Folders-by-Feature	Structure
ou	Estrutura	de	Pastas-por-Recurso
Crie	pastas	nomeadas	para	cada	recurso	que	elas	representam.	Quando	uma	pasta
cresce	ao	ponto	de	conter	mais	de	7	arquivos,	comece	considerar	a	criação	de	uma
pasta	para	eles.	O	seu	limite	pode	ser	diferente,	por	isso,	ajuste	conforme	necessário.
Por	que?	O	desenvolvedor	pode	localizar	o	código,	identificar	o	que	cada	arquivo
representa	em	resumo,	a	estrutura	é	plana	como	deve	ser,	e	não	há	nenhum	nome
repetido	ou	redundante.
Por	que?	As	orientações	LIFT	estão	todas	sendo	respeitadas.
Angular	Style	Guide	traduzido
61Application	Structure
Por	que?	Através	da	organização	do	conteúdo,	ajuda	a	reduzir	o	app	de	tornar-se
desordenado	e	mantêm	alinhado	com	as	diretrizes	LIFT.
Por	que?	Quando	há	um	grande	número	de	arquivos	(10+)	localizá-los	é	mais	fácil
com	estruturas	de	pastas	consistentes	e	mais	difícil	em	estruturas	planas.
/**
	*	recomendado
	*/
app/
				app.module.js
				app.config.js
				app.routes.js
				components/
								calendar.directive.js
								calendar.directive.html
								user-profile.directive.js
								user-profile.directive.html
				layout/
								shell.html
								shell.controller.js
								topnav.html
								topnav.controller.js
				people/
								attendees.html
								attendees.controller.js
								speakers.html
								speakers.controller.js
								speaker-detail.html
								speaker-detail.controller.js
				services/
								data.service.js
								localstorage.service.js
								logger.service.js
								spinner.service.js
				sessions/
								sessions.html
								sessions.controller.js
								session-detail.html
								session-detail.controller.js
Angular	Style	Guide	traduzido
62Application	Structure
Nota:	Não	estruture	seu	aplicativo	usando	pastas-por-tipo.	Isto	requer	alternar	entre
várias	pastas	ao	trabalhar	em	um	recurso	e	fica	difícil	de	manejar	quando	o	aplicativo
cresce	rapidamente	para	5,	10	ou	25+	views	e	controllers	(e	outros	recursos),	o	que
torna	mais	difícil	do	que	pasta-por-recurso	para	localizar	arquivos.
Angular	Style	Guide	traduzido
63Application	Structure
/*
*	evite
*	Alternativa	pastas-por-tipo.
*	Eu	recomendo	"pastas-por-recurso".
*/
app/
				app.module.js
				app.config.js
				app.routes.js
				controllers/
								attendees.js
								session-detail.js
								sessions.js
								shell.js
								speakers.js
								speaker-detail.js
								topnav.js
				directives/
								calendar.directive.js
								calendar.directive.html
								user-profile.directive.js
								user-profile.directive.html
				services/
								dataservice.js
								localstorage.js
								logger.js
								spinner.js
				views/
								attendees.html
								session-detail.html
								sessions.html
								shell.html
								speakers.html
								speaker-detail.html
								topnav.html
De	volta	ao	topo
Angular	Style	Guide	traduzido
64Application	Structure
Modularity
ou	Modularidade
Many	Small,	Self	Contained	Modules
ou	Muitos	módulos	pequenos	e	independentes
Crie	pequenos	módulos	que	encapsulem	uma	única	responsabilidade.
Por	que?	Aplicações	modulares	tornam	fácil	o	acoplamento,	pois	permitem	que	as
equipes	de	desenvolvimento	construam	fatias	verticais	das	aplicações	e	juntem	tudo	de
forma	incremental.	Isto	significa	que	podemos	acoplar	novos	recursos	enquanto	os
desenvolvemos.
Create	an	App	Module
ou	Crie	um	módulo	da	aplicação
Crie	um	módulo	raiz	para	a	aplicação,	cujo	papel	é:	reunir	todos	os	outros	módulos	e
funcionalidades	da	sua	aplicação.	Nomeie	ele	de	acordo	com	a	sua	aplicação.
Por	que?	Angular	incentiva	padrões	de	modularidade	e	de	separação.	Criando	um
módulo	raiz	da	aplicação	cujo	papel	é	o	de	amarrar	os	outros	módulos	juntos,	fica	muito
simples	de	adicionar	ou	remover	módulos	na	sua	aplicação.
Keep	the	App	Module	Thin
ou	Mantenha	o	módulo	da	aplicação	leve
Somente	coloque	a	lógica	para	reunir	o	aplicativo	no	módulo	da	aplicação.	Deixe	os
recursos	em	seus	próprios	módulos.
Por	que?	Adding	additional	roles	to	the	application	root	to	get	remote	data,	display
views,	or	other	logic	not	related	to	pulling	the	app	together	muddies	the	app	module	and
make	both	sets	of	features	harder	to	reuse	or	turn	off.	Por	que?	Colocar	funções
adicionais	na	raiz	da	aplicação	para	obter	dados	remoto,	modos	de	exibição,	ou	outra
lógica	não	relacionada	com	o	acoplamento	do	aplicativo,	torna	mais	difícil	reutilizar	os
recursos	ou	mesmo,	desligá-los.
Por	que?	O	módulo	da	aplicação	torna-se	um	manifesto	que	descreve	os	módulos	que
ajudam	a	definir	a	aplicação.
Angular	Style	Guide	traduzido
65Modularity
Feature	Areas	are	Modules
ou	Áreas	de	recursos	são	módulos
Crie	módulos	que	representem	áreas	de	recursos,	como:	layout,	serviços
compartilhados	e	reutilizados,	dashboards	e	recursos	específicos	do	aplicativo	(por
exemplo,	clientes,	administrativo,	vendas).
Por	que?	Módulos	independentes	podem	ser	adicionados	na	aplicação	com	pouco	ou
nenhum	esforço.
Por	que?	Sprints	ou	iterações	podem	focar	em	áreas	de	recursos	e	acoplá-los	na
aplicação	ao	fim	da	sprint	ou	iteração.
Por	que²:	Separando	as	áreas	de	recursos	em	módulos,	fica	fácil	de	testar	os	módulos
em	isolamento	e	de	reutilizar	o	código.
Reusable	Blocks	are	Modules
ou	Blocos	reutilizáveis	são	módulos
Crie	módulos	que	representam	blocos	reutilizáveis	da	aplicação	para	serviços	comuns,
como:	tratamento	de	exceção,	log,	diagnósticos,	segurança	e	armazenamento	local.
Porque?	Esses	tipos	de	recursos	são	necessários	em	muitas	aplicações,	então
mantê-los	separados	em	seus	próprios	módulos	os	torna	genéricos	e	assim,	podem	ser
reutilizados	em	diferentes	aplicações.
Module	Dependencies
ou	Dependências	do	módulo
O	módulo	raiz	da	aplicação	depende	de	módulos	de	recursos	específicos	do	aplicativo
e	de	qualquer	módulo	compartilhado	ou	reutilizado.
Angular	Style	Guide	traduzido
66Modularity
Por	que?	O	módulo	principal	do	aplicativo	contém	um	rápido	manifesto	para	identificar
os	recursos	da	aplicação.
Por	que?	Cada	área	de	recurso	contém	um	manifesto	mostrando	as	suas
dependências,	assim,	ela	pode	ser	colocada	como	uma	dependência	em	outras
aplicação	e	ainda	continuar	funcionando.
Por	que?	Recursos	intra-aplicação	como	serviços	compartilhados	de	dados,	tornam-se
muito	mais	fácil	de	localizar	e	compartilhar	atráves	do		app.core		(escolha	o	seu	nome
favorito	para	esse	módulo).
Nota:	Essa	é	uma	estratégia	para	consistência.	Existem	muitas	outras	boas	opções.
Escolha	uma	que	seja	consistente,	que	siga	as	regras	de	dependência	do	Angular,	e
que	seja	fácil	de	manter	e	escalar.
As	minhas	estruturas	podem	variar	ligeiramente	entre	os	projetos,	mas	todas	elas
seguem	estas	diretrizes	para	estrutura	e	modularidade.	A	implementação	pode
variar	dependendo	dos	recursos	e	do	time.	Em	outras	palavras,	não	fique	preso
somente	a	uma	estrutura	mas	justifique	sua	estrutura	usando	consistência,
facilidade	de	manutenção	e	eficiência	em	mente.
Em	um	aplicativo	pequeno,	você	também	pode	considerar	colocar	todas	as
dependẽncias	compartilhadas	no	módulo	principal	do	aplicativo,	onde	os	módulos
de	recursos	não	tem	dependências	diretas.	Isso	torna	mais	fácil	de	manter	a
aplicação,	mas	torna	mais	difícil	de	reutilizar	os	módulos	fora	dessa	aplicação.
Angular	Style	Guide	traduzido
67Modularity
De	volta	ao	topo
Angular	Style	Guide	traduzido
68Modularity
Angular	$	Wrapper	Services
Angular	Style	Guide	traduzido
69Angular	$	Wrapper	Services
Testing
Testes	unitários	ajudam	a	manter	o	código	limpo,	tal	como,	eu	inclui	algumas
recomendações	de	fundamentos	para	testes	unitários	com	links	para	mais	informações.
Escreva	testes	com	Histórias	(Stories)
Escreva	um	grupo	de	testes	para	cada	história.	Comece	com	um	teste	em	branco	e
preencha-o	conforme	você	for	escrevendo	o	código	para	a	história.
Por	que?	Escrevendo	uma	descrição	de	teste	te	ajudará	a	definir	claramente	o	que	a
sua	história	vai	fazer	ou	não	vai	fazer	e	como	você	poderá	mensurar	o	sucesso.
it('should	have	Avengers	controller',	function()	{
				//TODO
});
it('should	find	1	Avenger	when	filtered	by	name',	function()	{
				//TODO
});
it('should	have	10	Avengers',	function()	{}
				//TODO	(mock	data?)
});
it('should	return	Avengers	via	XHR',	function()	{}
				//TODO	($httpBackend?)
});
//	and	so	on
Frameworks	para	Testes
Para	teste	unitários	use	Jasmine	ou	Mocha.
Por	que?	Ambos,	Jasmine	e	Mocha	são	amplamente	utilizados	na	comunidade
AngularJS.	Ambos	são	estáveis,	são	mantidos	e	provém	features	de	teste	robustas.
Nota:	Se	escolher	Mocha,	também	considere	a	escolha	de	uma	Assert	Library	como
Chai.
Test	Runner
Use	Karma	como	seu	test	runner.
Angular	Style	Guide	traduzido
70Testing
Por	que?	Karma	é	fácil	de	configurar	para	executar	apenas	uma	vez	ou
automaticamente	enquanto	você	altera	seu	código.
Por	que?	Karma	se	integra	facilmente	com	seu	processo	de	Integração	Contínua	ou
através	do	Grunt	ou	Gulp.
Por	que?	Algumas	IDE's	estão	começando	a	se	integrar	com	o	Karma,	como
WebStorm	e	Visual	Studio.
Por	que?	Karma	funciona	muito	bem	com	os	líderes	de	automação	de	tarefas,	como
Grunt	(com	grunt-karma)	e	Gulp	(com	gulp-karma).
Stubbing	e	Spying
Utilize	Sinon	para	stubbing	e	spying.
Por	que?	Sinon	funciona	bem	tanto	com	Jasmine	quanto	com	Mocha	e	amplia	as
features	de	stubbing	e	spying	que	eles	oferecem.
Por	que?	Sinon	faz	ficar	mais	fácil	alternar	entre	Jasmine	e	Mocha,	se	você	quiser
tentar	ambos.
Headless	Browser
Use	PhantomJS	para	executar	seus	testes	no	servidor.
Por	que?	PhantomJS	é	um	headless	browser	que	executa	os	testes	sem	um
navegador	"visual".	Ou	seja,	você	não	precisa	instalar	Chrome,	Safari,	IE	ou	outros
navegadores	no	seu	servidor.
Nota:	Você	deve	continuar	testando	em	todos	os	navegadores	em	seu	ambiente,
conforme	apropriado	para	seu	público	alvo.
Análise	de	Código
Execute	JSHint	no	seus	testes.
Por	que?	Testes	são	códigos.	O	JSHint	ajuda	a	identificar	problemas	de	qualidade	de
código	que	podem	fazer	com	que	o	teste	execute	de	maneira	errada.
Ignore	algumas	regras	globais	do	JSHint	no	seus	testes
Faça	com	que	as	regras	de	teste	permitam	globais	comuns,	tais	como		describe		e
	expect	.
Angular	Style	Guide	traduzido
71Testing
Por	que?	Seus	testes	são	codigos	e	como	tal	necessitam	da	mesma	atenção	e	regras
de	qualidade	que	todo	o	seu	código	de	produção.	No	entanto,	as	variáveis	globais
usadas	pelo	framework	de	teste,	por	exemplo,	podem	ser	ignoradas	para	que	você	as
utilize	em	seus	testes.
/*	global	sinon,	describe,	it,	afterEach,	beforeEach,	expect,	inject	*/
De	volta	ao	topo
Angular	Style	Guide	traduzido
72Testing
Animations
ou	Animações
Utilização
Use	animações	com	AngularJS	para	transitar	suavemente	entre	a	visualização	de
views	e	elementos	visuais	primários.	Inclúa	o	módulo	ngAnimate.	Os	três	princípios	são
sutilidade,	suavidade	e	sem	remendos.
Por	que?	Animações	sutis	podem	melhorar	a	Experiência	de	Usuário	(UX)	quando
usadas	adequadamente.
Por	que?	Animações	sutis	podem	aumentar	a	sensação	de	performance	durante	a
alteração	entre	views.
Sub	Second
Use	animações	de	curta	duração.	Eu	geralmente	começo	com	300ms	e	ajusto
conforme	necessário.
Por	que?	Animações	de	longa	duração	podem	impactar	negativamente	na	experiência
do	usuário	e	em	sua	percepção	de	desempenho,	dando	a	impressão	de	ser	uma
aplicação	lenta.
animate.css
Use	animate.css	para	animações	convencionais.
Por	que?	As	animações	fornecidas	por	animate.css	são	rápidas,	suaves	e	fáceis	de
adicionar	à	sua	aplicação.
Por	que?	Provê	consistência	em	suas	animações.
Por	que?	animate.css	amplamente	utilizado	e	testado.
Nota:	Leia	este	excelente	post	do	Matias	Niemelä	sobre	Angular	Animations
De	volta	ao	topo
Angular	Style	Guide	traduzido
73Animations
Comments
ou	Comentários
jsDoc
Se	você	planeja	produzir	documentação,	use	a	sintaxe		jsDoc		para	documentar
nomes,	descrições,	parâmetros	e	retornos	de	funções.	Use		@namespace		e		@memberOf	
para	adequar	à	estrutura	de	sua	aplicação.
Por	que?	Você	pode	gerar	(e	regerar)	documentação	a	partir	do	seu	código	ao	invés
de	escrever	do	zero.
Por	que?	Fornece	consistência	utilizando	uma	ferramenta	comum	no	mercado.
Angular	Style	Guide	traduzido
74Comments
/**
	*	Logger	Factory
	*	@namespace	Factories
	*/
(function()	{
		angular
						.module('app')
						.factory('logger',	logger);
		/**
			*	@namespace	Logger
			*	@desc	Application	wide	logger
			*	@memberOf	Factories
			*/
		function	logger($log)	{
						var	service	=	{
									logError:	logError
						};
						return	service;
						////////////
						/**
							*	@name	logError
							*	@desc	Logs	errors
							*	@param	{String}	msg	Message	to	log
							*	@returns	{String}
							*	@memberOf	Factories.Logger
							*/
						function	logError(msg)	{
										var	loggedMsg	=	'Error:	'	+	msg;
										$log.error(loggedMsg);
										return	loggedMsg;
						};
		}
})();
De	volta	ao	topo
Angular	Style	Guide	traduzido
75Comments
JS	Hint
Use	um	arquivo	de	Options
Use	JS	Hint	para	inspecionar	seu	JavaScript	e	não	se	esqueça	de	customizar	o	arquivo
de	configurações	e	versioná-lo	no	controle	de	versão.	Veja	JS	Hint	docs	para	detalhes
a	respeito	das	opções.
Por	que?	Fornece

Continue navegando