Buscar

desenvolvimento-web-front-end-com-angular

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 110 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 110 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 110 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

1.1
2.1
2.2
2.3
2.4
2.5
2.6
2.7
2.8
2.9
2.10
2.11
3.1
3.2
3.3
3.4
3.5
3.6
Tabela	de	conteúdos
Introdução
Conceitos	iniciais
Iniciando	com	o	Angular
Angular	CLI
Software	de	gerenciamento	escolar
Criando	o	projeto
Depurando	código	no	browser
Iniciando	com	teste	de	software
Apresentando	a	lista	de	disciplinas
Cadastrando	uma	disciplina
Excluindo	uma	disciplina
Editando	dados	de	uma	disciplina
Depurando	código	no	browser
Nível	intermediário
Interação	entre	componentes
Serviços
Acessando	dados	externos	de	forma	assíncrona
Acessando	dados	de	uma	API	HTTP
Rotas
Feature-modules
1
Desenvolvimento	web	front-end	com
Angular
Este	é	um	livro	open-source,	tanto	no	conteúdo	quanto	no	código-fonte	associado.	O
conteúdo	é	resultado	de	algumas	práticas	com	o	Framework	Angular	e	segue	uma
abordagem	prática,	com	foco	no	entendimento	de	conceitos	e	tecnologias	no	contexto	do
desenvolvimento	de	um	software	de	gerenciamento	escolar.
Com	o	passar	dos	capítulos	será	possível	perceber	a	utilização	iterativa	e	incremental	de
recursos	até	chegar	à	conclusão	do	desenvolvimento	do	gerenciador	escolar.
Parte	do	conteúdo	do	livro	é	baseada	na	documentação	oficial	do	Angular,	disponível	em
https://angular.io.
Como	o	Angular	é	um	projeto	em	constante	desenvolvimento	(pelo	menos	até	agora)	serão
publicadas	atualizações	no	conteúdo	do	livro	sempre	que	possível,	para	refletir	novos
recursos	e	funcionalidades.	No	momento,	o	conteúdo	do	livro	é	baseado	na	versão	5.2.0.
Conhecimentos	desejáveis
Este	livro	aborda	o	desenvolvimento	de	software	front-end	para	a	web	do	ponto-de-vista	do
Angular.	Isso	quer	dizer	que	não	trata	de	conceitos	iniciais	de	HTML,	CSS,	JavaScript,
TypeScript	e	Bootstrap.	Entretanto,	os	conceitos	fundamentais	dessas	tecnologias	vão
sendo	apresentados	no	decorrer	dos	capítulos,	conforme	surge	a	necessidade	deles.
Para	aprender	mais	sobre	essas	tecnologias	recomendo	essas	fontes:
TypeScript:	Documentação	oficial	do	TypeScript	-	Microsoft,	TypeScript	Deep	Dive
HTML,	CSS	e	JavaScript:	W3Schools
Boostrap:	Documentação	oficial	do	Bootstrap
Código-fonte
O	software	Angular	Escola,	que	serve	como	apoio	para	este	livro	está	disponível
gratuitamente	no	Github:	https://github.com/jacksongomesbr/angular-escola.	O	repositório
provê	branches	que	demonstram	a	evolução	do	desenvolvimento	do	software	na	mesma
ordem	dos	capítulos	do	livro.	Cada	capítulo,	se	necessário,	indica	qual	branch	utilizar.
Introdução
2
https://angular.io
https://www.typescriptlang.org/docs/home.html
https://www.gitbook.com/book/basarat/typescript/details
https://www.w3schools.com/
http://getbootstrap.com/docs/4.0/getting-started/introduction/
https://github.com/jacksongomesbr/angular-escola
Dependências
Para	utilizar	o	código-fonte	do	livro	e	desenvolver	em	Angular	você	precisa,	antes,	montar
seu	ambiente	de	desenvolvimento	com	algumas	ferramentas:
1.	 Git:	disponível	em	https://git-scm.com/
2.	 Node.js:	disponível	em	https://nodejs.org	representa	um	ambiente	de	execução	do
JavaScript	fora	do	browser	e	também	inclui	o	npm,	um	gerenciador	de	pacotes
3.	 Editor	de	textos	ou	IDE:	atualmente	há	muitas	opções,	mas	destaco	estas:
i.	 VisualStudioCode:	disponível	em	https://code.visualstudio.com/
ii.	 Nodepad++:	disponível	em	https://notepad-plus-plus.org/
iii.	 PHPStorm	ou	WebStorm:	disponíveis	em	https://www.jetbrains.com
Visão	geral
A	tabela	a	seguir	apresenta	uma	visão	geral	dos	conceitos	apresentados	ou	discutidos	em
cada	capítulo	do	livro.
Capítulo Conteúdos
Iniciando	com	o	Angular Arquitetura	do	Angular;	Elementos	da	Arquitetura	doAngular	(ex.:	módulos	e	componentes)
Angular	CLI Ferramenta	Angular	CLI;	Comandos
Criando	o	projeto Ferramenta	Angular	CLI;	Comando	new
Apresentando	a	lista	de
disciplinas Data	binding;	Diretivas;	Eventos
Cadastrando	uma	disciplina Formulários;	Two-way	Data	binding;	Eventos
Excluindo	uma	disciplina Two-way	Data	Binding;	Eventos
Editando	dados	de	uma
disciplina Formulários;	Two-way	Data	Binding;	Eventos
Melhorando	a	interface	gráfica
do	CRUD	de	disciplinas
Formulários;	Data	Binding;	Eventos;	Bootstrap;	Font
Awesome
Interação	entre	componentes Criação	de	componentes;	Input	e	Output	parainteração	entre	componentes
Introdução
3
https://git-scm.com/
https://nodejs.org
https://code.visualstudio.com/
https://notepad-plus-plus.org/
https://www.jetbrains.com
Iniciando	com	o	Angular
[info]	Objetivos	do	capítulo:
demonstrar	os	elementos	da	Arquitetura	do	Angular
demonstrar	a	relação	entre	os	elementos	da	Arquitetura	do	Angular	e	arquivos	do
projeto
Branch:	iniciando
O	Angular	é	um	framework	para	o	desenvolvimento	de	software	front-end.	Isso	quer	dizer
que	utiliza	tecnologias	padrão	do	contexto	web	como	HTML,	CSS	e	uma	linguagem	de
programação	como	JavaScript	ou	TypeScript.
Um	software	desenvolvido	em	Angular	é	composto	por	diversos	elementos	como:	módulos,
componentes,	templates	e	serviços.	Esses	elementos	fazem	parte	da	arquitetura	do
Angular,	que	é	ilustrada	pela	figura	a	seguir.
Essa	arquitetura	de	software	orientada	a	componentes	implementa	conceitos	de	dois
padrões	de	arquitetura	de	software:
MVC	(Model,	View,	Controller)	é	um	padrão	de	software	que	separa	a	representação	da
informação	(Model)	da	interação	do	usuário	com	ele	(View-Controller).	Geralmente,
Model	e	Controller	são	representados	por	código	em	linguagem	de	programação
(classes	e/ou	funções)	e	View	é	representado	por	HTML	e	CSS.
MVVM	(Model,	View,	View-Model)	é	um	padrão	de	software	semelhante	ao	MVC,	com
a	diferença	de	que	o	View-Model	utiliza	recurso	de	data	binding	(mais	sobre	isso
Iniciando	com	o	Angular
4
https://github.com/jacksongomesbr/angular-escola/tree/iniciando
depois)	para	fazer	com	que	a	View	seja	atualizada	automaticamente	quando	ocorrer
uma	modificação	no	Model.
No	contexto	do	Angular	esses	elementos	são	descritos	conforme	as	seções	a	seguir.
Elementos	da	Arquitetura	do	Angular
Módulos
Módulos	representam	a	forma	principal	de	modularização	de	código.	Isso	significa	que	um
módulo	é	um	elemento	de	mais	alto	nível	da	arquitetura	do	Angular	e	é	composto	por	outros
elementos,	como	componentes	e	serviços.
Um	software	desenvolvido	em	Angular	possui	pelo	menos	um	módulo,	chamado	root
module	(módulo	raiz).	Os	demais	módulos	são	chamados	feature	modules	(módulos	de
funcionalidades).
Bibliotecas
Bibliotecas	funcionam	como	um	agrupador	de	elementos	de	software	desenvolvido	em
Angular.	Bibliotecas	oficiais	têm	o	prefixo		@angular	.	Geralmente	é	possível	instalar
bibliotecas	utilizando	o	npm	(gerenciador	de	pacotes	do	NodeJs).
Uma	biblioteca	pode	conter	módulos,	componentes,	diretivas	e	serviços.
Componentes
Um	componente	está,	geralmente,	relacionado	a	algo	visual,	ou	seja,	uma	tela	ou	parte
dela.	Nesse	sentido,	um	componente	possui	código	(Controller)	que	determina	ou	controla
o	comportamento	da	interação	com	o	usuário	(View	ou	Template).
O	Template	determina	a	parte	visual	do	componente	e	é	definido	por	código	HTML	e	CSS,
além	de	recursos	específicos	do	Angular,	como	outros	componentes	e	diretivas.
Metadados
Metadados	são	um	recurso	do	Angular	para	adicionar	detalhes	a	classes.	Isso	é	utilizado
para	que	o	Angular	interprete	uma	classe	como	um	Módulo	ou	como	um	Componente,	por
exemplo.
Data	binding
Iniciando	com	o	Angular
5
Data	binding	(que	seria	algo	como	"vinculação	de	dados"	em	português)	é	um	reucrso	do
Angular	que	representa	um	componente	importante	da	sua	arquitetura.	Considere	os
seguintes	elementos:
um	Model	define	dados	que	serão	apresentados	no	Template
um	Template	apresenta	os	dados	do	Model
um	Controller	ou	um	View-Model	determina	o	comportamento	do	Template
Se	o	Controller	atualiza	o	Model,	então	o	Template	tem	que	ser	atualizado
automaticamente.	Se	o	usuário	atualiza	o	Model	por	meio	do	Template	(usando	um
formulário,	por	exemplo)	o	Controller	também	precisa	ter	acesso	ao	Model	atualizado.	O
Data	Binding	atua	garantindo	que	esse	processo	ocorra	dessa	forma.
Diretivas
Diretivas	representam	um	conceito	do	Angular	que	é	um	pouco	confuso.	Na	prática,	um
Componenteé	uma	Diretiva	com	um	Template.	Assim,	um	Componente	é	um	tipo	de
Diretiva,	que	nem	sempre	está	relacionada	a	algo	visual.	Angular	define	dois	tipos	de
diretivas:
Diretivas	Estruturais:	modificam	o	Template	dinamicamente	por	meio	de	manipulação
do	DOM	(Document	Object	Model),	adicionando	ou	removendo	elementos	HTML
Diretivas	de	Atributos:	também	modificam	o	Template,	mas	operam	sobre	elementos
HTML	já	existentes
Serviços
Um	Serviço	é	uma	abstração	do	Angular	utilizado	para	isolar	a	lógica	de	negócio	de
Componentes.	Na	prática,	um	Serviço	é	representado	por	uma	classe	com	métodos	que
podem	ser	utilizados	em	Componentes.	Para	isso,	para	que	um	Componente	utilize	um
serviço,	o	Angular	utiliza	o	conceito	de	Injeção	de	Dependência	(DI,	do	inglês
Dependency	Injection).	DI	é	um	padrão	de	software	que	faz	com	que	dependências	sejam
fornecidas	para	quem	precisar.	Na	prática,	o	Angular	identifica	as	dependências	de	um
Componente	e	cria	automaticamente	instâncias	delas,	para	que	sejam	utilizadas
posteriormente	no	Componente.
Enquanto	esses	elementos	da	Arquitetura	do	Angular	representam	conceitos,	é	importante
visualizar	a	relação	deles	com	elementos	práticos	do	software,	ou	seja,	código.	Para	isso,	a
seção	a	seguir	apresenta	a	estrutura	padrão	de	um	software	desenvolvido	em	Angular.
Iniciando	com	o	Angular
6
Estrutura	padrão	de	um	software	desenvolvido
em	Angular
Um	software	desenvolvido	em	Angular	é	representado	por	vários	arquivos	HTML,	CSS,
TypeScript	e	de	configuração	(geralmente	arquivos	em	formato	JSON).
+	src
		+	app
				-	app.component.css
				-	app.component.html
				-	app.component.ts
				-	app.module.ts
		+	assets
		+	environments
				-	environment.prod.ts
				-	environment.ts
		-	index.html
		-	maint.ts
		-	polyfills.ts
		-	styles.css
		-	tsconfig.app.json
		-	typings.d.ts
-	.angular-cli.json
-	package.json
-	tsconfig.json
-	tslint.json
No	diretório	raiz	do	software:
	src	:	contém	o	código-fonte	do	software	(módulos,	componentes	etc.)
	.angular-cli.json	:	contém	configurações	do	projeto	Angular	(nome,	scripts	etc.)
	package.json	:	contém	configurações	do	projeto	NodeJS	(um	projeto	Angular	utiliza
NodeJS	para	gerenciamento	de	pacotes	e	bibliotecas,	por	exemplo)
	tsconfig.json		e		tslint.json	:	contêm	configurações	do	processo	de	tradução	de
código	TypeScript	para	JavaScript
No	diretório		src	:
	app	:	contém	o	root	module	e	os	demais	feature	modules	do	projeto
	assets	:	contém	arquivos	CSS,	JSON	e	scripts,	por	exemplo
	environments	:	contém	arquivos	de	configuração	do	ambiente	de	desenvolvimento
(	environment.ts	)	e	de	produção	(	environment.prod.ts	)
	index.html	:	contém	o	código	HTML	inicial	para	o	projeto	e	inclui	o	componente
principal	do	root	module
	main.ts	:	contém	o	código	TypeScript	necessário	para	iniciar	o	software	(processo
Iniciando	com	o	Angular
7
chamado	de	Bootstrap)
	polyfills.ts	:	contém	código	TypeScript	que	indica	scripts	adicionais	a	serem
carregados	pelo	Browser	para	funcionamento	do	software	como	um	todo	e	para
questões	de	compatibilidade	com	versões	antigas	de	Browsers
	style.css	:	contém	o	código	CSS	para	definir	estilos	globais	para	o	software
	tsconfig.app.json		e		typings.d.ts	:	complementam	configurações	do	arquivo
	../tsconfig.json		específicas	para	o	software	em	questão
No	diretório		app	:
	app.component.css	,		app.component.html		e		app.component.ts	:	definem	o	component
AppComponent,	respectivamente:	apresentação	por	meio	de	CSS,	Template	e
Controller.	Basicamente,	estes	três	arquivos	formam	a	base	de	todo	componente
	app.module.ts	:	código	TypeScript	que	define	o	root	module
Esse	capítulo	incial	do	livro	apresentou	conceitos	importantes	do	Angular.	A	maior	parte	dos
conceitos	está	diretamente	relacionada	a	código-fonte	(HTML,	CSS,	TypeScript	e	JSON)
que	estão	em	arquivos	do	diretório	onde	encontra-se	o	projeto.
Sempre	que	necessário,	volte	a	esse	capítulo	para	revisar	conceitos	do	Angular.	Muito
provavelmente,	mesmo	desenvolvedores	experientes	precisem,	de	tempos	em	tempos,
rever	essas	definições	da	arquitetura	do	Angular.
Iniciando	com	o	Angular
8
Angular	CLI
[info]	Objetivos	do	capítulo:
apresentar	o	Angular	CLI
apresentar	comandos	para	criação	de	projetos,	módulos,	componentes	e	outros
elementos
apresentar	o	arquivo		.angular-cli.json	
O	Angular	CLI	(disponível	em	https://cli.angular.io)	é	uma	ferramenta	para	inicializar,
desenvolver,	criar	conteúdo	e	manter	software	desenvolvido	em	Angular.	A	principal
utilização	dessa	ferramenta	começa	na	criação	de	um	projeto.	Você	pode	fazer	isso
manualmente,	claro,	mas	lidar	com	todas	as	configurações	necessárias	para	o	seu	software
Angular	pode	não	ser	algo	fácil,	mesmo	se	você	for	um	desenvolvedor	com	nível	de
conhecimento	médio	a	avançado.
[info]	cê-éle-í?
Como	parte	do	vocabulário	do	Angular,	geralmente	é	interessante	pronunciar	angular
cê-ele-i,	isso	mesmo,	CLI	é	uma	sigla	para	Command	Line	Interface	(no	português
Interface	de	Linha	de	Comando).	Assim,	usar	"cli"	não	é	exclusividade	alguma	do
Angular	--	provavelmente	você	verá	isso	em	outros	projetos.
As	seções	a	seguir	vão	apresentar	como	instalar	e	utilizar	o	Angular	CLI	para	desenvolver
software	Angular.
Instalando
O	Angular	CLI	é	distribuído	como	um	pacote	do	NodeJS,	então	você	não	encontrará	um
instalador,	como	acontece	com	software	tradicional.	Ao	invés	disso,	você	precisa	de	um
ambiente	de	desenvolvimento	com	o	NodeJS	instalado	(esse	capítulo	não	trata	disso).
Depois	de	ter	o	NodeJS	instalado,	a	instalação	do	Angular	CLI	passa	pela	utilização	do
npm,	o	gerenciador	de	pacotes	do	NodeJS.	Para	isso,	a	seguinte	linha	de	comando	deve
ser	executada:
npm	install	-g	@angular/cli
Isso	fará	uma	instalação	global	do	Angular	CLI	(por	isso	o		-g		na	linha	de	comando)	e
disponibilizará	o	programa		ng	.
Angular	CLI
9
https://cli.angular.io
[warning]	Problemas	na	instalação?
Podem	acontecer	certos	problemas	na	instalação	do	Angular	CLI.	Por	exemplo,	você
pode	estar	com	uma	versão	bem	desatualizada	do	NodeJS	e	do	npm.	Assim,	garanta
sempre	que	seu	ambiente	de	desenvolvimento	esteja	com	as	versões	corretas	desses
programas.
Outra	situação	é	se	você	tiver	problemas	para	fazer	uma	instalação	global.	Se	for	o
caso,	faça	uma	instalação	local	(sem	o		-g		na	linha	de	comando)	e	execute	o
programa		ng		que	está	no	caminho		./node_modules/.bin/ng	.
Comandos
O	Angular	CLI	disponibiliza	uma	série	de	comandos,	que	são	fornecidos	como	parâmetros
para	o	programa	ng.	Além	disso,	cada	comando	possui	diversas	opções	(ou	flags).	Faça	o
exercício	de	se	acostumar	a	essas	opções	para	aumentar	a	sua	produtividade.
Os	principais	comandos	serão	apresentados	nas	seções	seguintes.
help
O	comando		help		é	muito	importante	porque	apresenta	uma	documentação	completa	do
Angular	CLI,	ou	seja,	todos	os	comandos	e	todas	as	suas	opções.
Exemplo:	documentação	completa
ng	help
Essa	linha	de	comando	apresenta	todos	os	comandos	e	todas	as	suas	opções.
Exemplo:	documentação	do	comando		new	:
ng	help	new
Essa	linha	de	comando	apresenta	apenas	as	opções	do	comando		new	.
As	opções	de	cada	comando	são	sempre	precedidas	de		--		(dois	traços).	Algumas	opções
aceitam	um	valor	e	geralmente	possuem	um	valor	padrão.
Exemplo:	comando	new	com	duas	opções
ng	new	escola-app	--skip-install	--routing	true	--minimal	true
Angular	CLI
10
Essa	linha	de	comando	fornece	três	opções	para	o	comando		new	:		--skip-install	,		--
routing		(que	recebe	o	valor		true	)	e		--minimal		(que	recebe	o	valor		true	).
new
O	comando		new		é	utilizado	para	criar	um	projeto	(um	software	Angular).	Exemplo:
ng	new	escola-app
Quando	a	linha	de	comando	do	exemplo	for	executada	será	criado	um	software	Angular
chamado	escola-app	e	estará	em	um	diretório	chamado		escola-app	,	localizado	a	partir	de
onde	a	linha	de	comando	estiver	sendo	executada.
A	parte	mais	interessante	de	criar	um	projeto	Angular	com	esse	comando	é	que	ele	cria
todos	os	arquivos	necessários	para	um	software	bastante	simples,	mas	funcional.
Para	cada	comando	do	Angular	CLI	é	possível	informar	opções.	Asopções	mais	usadas	do
comando		new		são:
	--skip-install	:	faz	com	que	as	dependências	não	sejam	instaladas
	--routing	:	se	for	seguida	de		true	,	o	comando	cria	um	módulo	de	rotas	(isso	será
visto	em	outro	capítulo
generate
O	comando		generate		é	utilizado	para	criar	elementos	em	um	projeto	existente.	Para
simplificar,	é	bom	que	o	Angular	CLI	seja	executado	a	partir	do	diretório	do	projeto	a	partir
de	agora.	Por	meio	desse	comando	é	possível	criar:
class
component
directive
enum
guard
interface
module
pipe
service
Como	acontece	com	outros	comandos,	o		generate		também	pode	ser	utilizado	por	meio	do
atalho		g	.
Exemplo:	criar	component	ListaDeDisciplinas
Angular	CLI
11
ng	generate	component	ListaDeDisciplinas
Essa	linha	de	comando	criará	o	diretório		./src/app/lista-de-disciplinas		e	outros	quatro
arquivos	nesse	mesmo	local:
	lista-de-disciplinas.component.css	
	lista-de-disciplinas.component.html	
	lista-de-disciplinas.component.spec.ts	
	lista-de-disciplinas.component.ts	
É	importante	notar	que	esses	arquivos	não	estão	vazios,	mas	já	contêm	código	que
mantém	o	software	funcional	e	utilizável.	Por	isso	o	Angular	CLI	considera	que	as	opções
(class,	component	etc.)	são	como	blueprints	(ou	plantas,	em	português).	Outra	coisa
importante	é	que	o	Angular	CLI	também	modificará	o	arquivo		./src/app/app.module.ts		se
necessário	(ou	outro	arquivo	que	represente	um	módulo	que	não	seja	o	root	module	--
mais	sobre	isso	depois).
serve
O	comando		serve		compila	o	projeto	e	inicia	um	servidor	web	local.	Por	padrão	o	servidor
web	executa	no	modo		--watch		,	que	reinicia	o	comando	novamente,	de	forma	incremental,
sempre	que	houver	uma	alteração	em	algum	arquivo	do	projeto,	e		--live-reload	,	que
recarrega	o	projeto	no	Browser	(se	houver	uma	janela	aberta)	sempre	que	houver	uma
mudança.
build
O	comando		build		compila	o	projeto,	mas	não	inicia	um	servidor	web	local.	Ao	invés	disso,
gera	os	arquivos	resultantes	da	compilação	em	um	diretório	indicado.
Veremos	mais	sobre	esses	e	outros	comando	no	decorrer	do	livro.
Angular	CLI
12
[info]	Espera,	compilação?
Como	já	disse,	você	pode	utilizar	JavaScript	ou	TypeScript	ao	desenvolver	projetos
Angular.	Isso	não	é	bem	assim.	Na	prática,	geralmente	você	encontrará	a
recomendação	(senão	uma	ordem)	de	utilizar	TypeScript.	O	problema	é	que	seu
Browser	não	entende	TypeScript,	por	isso	é	necessário	um	processo	de	tradução	do
código	TypeScript	para	JavaScript.	E	não	é	só	isso.	Há	vários	recursos	utilizados	no
projeto	Angular	criado	com	TypeScript	que	precisam	de	ajustes	para	que	funcionem	no
seu	Browser.
Por	isso	os	comandos		serve		e		build		são	tão	importantes	e	--	por	que	não	dizer?	--
browser-friendly	=)
Angular	CLI
13
Software	de	gerenciamento	escolar
[info]	Objetivo	do	capítulo:
apresentar	informações	sobre	gerenciamento	escolar
apresentar	requisitos	do	software	de	gerenciamento	escolar
Neste	livro	você	verá	informações	técnicas	sobre	desenvolvimento	de	software	web	com
Angular	e	isso	é	colocado	em	prática	por	meio	do	desenvolvimento	de	um	software	de
gerenciamento	escolar.	Antes	disso,	entretanto,	vamos	ao	contexto:	gerenciamento	escolar.
Contexto	da	escola
No	contexto	desse	livro	o	gerenciamento	escolar	é	aplicado	em	uma	escola	fictícia	com	as
seguintes	características:
a	estrutura	de	pessoal	(recursos	humanos)	tem	as	seguintes	características:
funcionários	são	pessoas	contratadas	para	ocupar	cargos	e	realizar	funções
um	funcionário	tem	um	cargo
um	funcionário	tem	uma	ou	mais	funções
um	funcionário	pode	ser:	administrativo	ou	docente
a	estrutura	acadêmica	da	escola	tem	as	seguintes	características:
há	três	níveis	de	ensino:	ensino	infantil,	ensino	fundamental,	ensino	médio
cada	nível	de	ensino	pode	ser	organizado	em	anos	de	ensino	e	cada	um	possui
disciplinas
a	relação	entre	nível	de	ensino	e	ano	de	ensino	é	chamada	de	estrutura	curricular,
cada	qual	com	disciplinas	e	suas	cargas	horárias	anuais
uma	turma	é	quando	um	item	do	componente	curricular	é	ministrado	durante	um
ano	letivo	e	tem	as	seguintes	características:
pode	ter	um	ou	mais	professores	por	disciplina
pode	ter	um	ou	mais	alunos
matrícula	é	quando	um	aluno	é	matriculado	em	uma	turma	e	cursa	todas
as	disciplinas	do	ano	letivo
fisicamente,	está	presente	em	uma	sala	de	aula	(sala	padrão)
uma	aula	é	quando	conteúdos	didáticos	de	uma	disciplina	da	turma	são
trabalhados	com	professores	e	alunos	em	horários	específicos	na	semana
uma	aula	pode	ter	participação	de	um	ou	mais	professores	[da	turma]
uma	aula	pode	ser	realizada	na	sala	de	aula	padrão	da	turma	ou	em
instalação	física
Software	de	gerenciamento	escolar
14
uma	aula	é	realizada	em	um	dia	da	semana,	em	um	horário	específico
(informação	utilizada	para	compor	a	grade	horária)
em	cada	aula	o	professor	registra	a	frequência	do	aluno	(presença	ou	falta)
cada	aula	tem	a	duração	de	50	minutos	e	conta	como	uma	hora	(na	Carga
Horária)
os	conteúdos	das	aulas	são	organizados	em	bimestres	e,	por	isso,	são	realizadas
avaliações	bimestrais,	totalizando	quatro	(para	cada	disciplina)	no	ano	letivo
ao	final	do	ano	letivo:
as	quatro	notas	são	utilizadas	para	compor	a	nota	final,	que	é	uma	média
aritmética	das	notas	dos	bimestres
o	aluno	é	considerado	"APROVADO"	na	disciplina	se	tiver	média	aritmética
igual	ou	superior	a	6,0	e	frequência	superior	a	75%
o	aluno	que	não	conseguir	nota	final	suficiente	pode	realizar	uma	prova	de
recuperação,	cuja	nota	substitui	a	nota	final.	Por	fim,	se	o	aluno	não	obtiver
nota	igual	ou	superior	a	6,0	na	recuperação	ele	é	considerado	"REPROVADO"
em	situações	excepcionais	o	aluno	pode	ser	considerado	"APROVADO"	em
conselho	de	classe	(uma	reunião	realizada	ao	final	do	ano	letivo	com	os
professores)
com	exceção	do	ensino	infantil,	o	aluno	só	pode	ser	matriculado	no	ano	seguinte
se	tiver	sido	aprovado	em	todas	as	disciplinas	do	ano	corrente
a	estrutura	física	da	escola	tem	as	seguintes	características:
uma	instalação	física	pode	ser:	prédio,	sala	admnistrativa,	laboratório	ou	sala	de
aula
Para	ilustrar	esse	contexto,	alguns	exemplos	de	estruturas	curriculares:
Figura	2.3.1	-	Exemplo	de	estrutura	curricular	do	Ensino	Médio	-	1º	ao	5º	ano
Software	de	gerenciamento	escolar
15
Figura	2.3.2	-	Exemplo	de	estrutura	do	Ensino	Fundamental	-	6º	ao	9º	ano
Figura	2.3.3	-	Exemplo	de	Estrutura	curricular	do	Ensino	Médio
Software	de	gerenciamento	escolar
16
Figura	2.3.4	-	Exemplo	de	Estrutura	curricular	do	Ensino	Infantil
Gerenciamento	escolar
Com	base	nas	características	da	escola	usada	nesse	contexto,	o	software	de
gerenciamento	escolar	compreende	os	seguintes	requisitos	conforme	os	atores:
gerente	do	sistema
gerenciar	o	cadastro	de	usuários	e	permissões	de	acesso
gerente	administrativo
gerenciar	o	cadastro	de	cargos
gerenciar	o	cadastro	de	funções
gerenciar	o	cadastro	de	funcionários
gerenciar	o	cadastro	de	instalações	físicas
gerente	de	ensino
gerenciar	o	cadastro	de	disciplinas
gerenciar	o	cadastro	de	níveis	de	ensino
gerenciar	o	cadastro	de	estruturas	curriculares
gerenciar	o	cadastro	de	turmas	(bem	como	professores	nas	turmas	e	horários)
gerenciar	o	cadastro	de	alunos	(geral)
gerenciar	o	cadastro	de	matrículas	(alunos	nas	turmas)
registrar	aprovação	ou	reprovação	excepcional	em	conselho	de	classe
professor
ver	as	turmas	em	que	ministra	disciplinas
ver	os	alunos	das	turmas	em	que	ministra	disciplinas
ver	a	agenda	de	aula	das	turmas	em	que	ministra	disciplinas	(turmas,	disciplinas,
salas	de	aula,	dias	da	semana	e	horários	de	aula)
ver	a	agenda	de	aula	da	escola	(todas	as	turmas	do	ano	letivo)
gerenciar	o	cadastro	de	frequência	dos	alunos	(nas	suas	turmas	e	disciplinas)
Software	de	gerenciamento	escolar
17
gerenciar	as	notas	das	avaliações	bimestrais	dos	alunos	(nas	suas	turmas	e
disciplinas)
aluno	(e/ou	pais	ou	responsáveis)
ver	a	estrutura	curricular	do	nível	e	ano	de	ensino	em	que	está	matriculado
ver	a	estrutura	curricular	de	todos	os	níveis	e	anos	de	ensino
ver	a	agenda	de	aula	da	turma	em	que	está	matriculado	(disciplinas,	professores,
salas	de	aula,	dias	da	semana	e	horários	de	aula)ver	o	histórico	acadêmico	(notas	e	situação	final	para	as	turmas	cursadas)
Uma	descrição	mais	completa	dos	requisitos	pode	ser	encontrada	aqui:
http://200.199.229.99/reqman/projects/3/documentation.pdf.
Software	de	gerenciamento	escolar
18
http://200.199.229.99/reqman/projects/3/documentation.pdf
Criando	o	projeto
[info]	Objetivos	do	capítulo:
demonstrar	como	utilizar	o	Angular	CLI	para	criar	o	projeto	angular-escola
apresentar	os	requisitos	de	software	que	serão	implementados	no	capítulo
Branch:	iniciando
O	capítulo	Angular	CLI	apresentou	essa	ferramenta,	comandos	e	opções.	A	primeira
utilização	da	ferramenta	está	na	criação	do	projeto	com	o	comando:
ng	new	angular-escola
Isso	fará	com	que	seja	criado	um	diretório		angular-escola		no	local	onde	o	comando	foi
executado.	Como	já	informado,	o	diretório	contém	código-fonte	de	um	software	Angular
funcional.	Para	vê-lo	em	execução	acesse	o	diretório		angular-escola		e	execute	o
comando:
npm	start
Esse	script	executa	o	comando		ng	serve		do	Angular	CLI	e	cria	um	servidor	web	local,	por
padrão	na	porta	4200.	Para	ver	o	software	em	funcionamento,	abra	o	endereço
	http://localhost:4200		no	seu	browser	de	preferência.	Mais	para	frente	podemos	discutir
um	pouco	mais	a	saída	desse	comando,	porque	é	muito	interessante.	O	resultado	deverá
ser	semelhante	ao	da	figura	a	seguir.
Criando	o	projeto
19
https://github.com/jacksongomesbr/angular-escola/tree/iniciando
Figura	2.4.1	-	Versão	inicial	do	software	em	execução	no	Browser
Esse	não	é	um	comando	do	Angular	CLI.	Antes,	é	um	comando	(script)	que	está	definido	no
arquivo		package.json	.
O	arquivo	package.json
O	arquivo		package.json		contém	informações	do	projeto,	scripts	e	dependências.	O	arquivo
criado	pelo	Angular	CLI	tem	mais	ou	menos	o	seguinte	conteúdo:
Criando	o	projeto
20
{
		"name":	"angular-escola",
		...
		"scripts":	{
				"ng":	"ng",
				"start":	"ng	serve",
				"build":	"ng	build	--prod",
				...
		},
		"private":	true,
		"dependencies":	{
				"@angular/animations":	"^5.2.0",
				"@angular/common":	"^5.2.0",
				"@angular/compiler":	"^5.2.0",
				"@angular/core":	"^5.2.0",
				"@angular/forms":	"^5.2.0",
				"@angular/http":	"^5.2.0",
				"@angular/platform-browser":	"^5.2.0",
				"@angular/platform-browser-dynamic":	"^5.2.0",
				"@angular/router":	"^5.2.0",
				"core-js":	"^2.4.1",
				"rxjs":	"^5.5.6",
				"zone.js":	"^0.8.19"
		},
		"devDependencies":	{
				"@angular/cli":	"1.6.6",
				"@angular/compiler-cli":	"^5.2.0",
				"@angular/language-service":	"^5.2.0",
				...
		}
}
Por	ser	um	conteúdo	em	formato	JSON,	o	interpretamos	da	seguinte	forma:
	name	:	é	o	atributo	que	define	o	nome	do	projeto	para	o	NodeJS	(nesse	ponto,	não	tem
a	ver	com	o	Angular)
	scripts	:	é	o	atributo	que	contém	scripts	que	podem	ser	executados	no	prompt
(exemplos:		npm	start		e		npm	run	build	).	Nesse	caso	esses	scripts	usam	o	Angular
CLI	(veja	os	valores	dos	atributos		start		e		build	)
	dependencies	:	é	o	atributo	que	define	as	dependências	do	projeto.	Basicamente,	as
dependências	atuais	são	padrão	para	software	desenvolvido	em	Angular.	Importante
notar	que	o	nome	de	cada	atributo	determina	o	pacote	(como		@angular/core	)	e	seu
valor	determina	a	versão	(como	 	̂ 5.2.0	,	indicando	a	versão	desses	pacotes	do
Angular)
	devDependencies	:	é	o	atributo	que	define	as	dependências	de	desenvolvimeto.	São
ferramentas	que	não	geram	código-fonte	que	será	distribuído	junto	com	o	software	que
está	sendo	desenvolvido
Criando	o	projeto
21
Examinando	o	código-fonte#0
Agora	que	você	já	conhece	um	pouco	mais	da	estrutura	do	software	Angular,	do	Angular
CLI	e	do	npm,	vamos	dar	uma	olhada	no	código-fonte	que	está	gerando	o	software	atual,
começando	pelo		AppComponent		e	seu	Template,	que	está	no	arquivo
	./src/app/app.component.html	,	cujo	trecho	de	conteúdo	é	apresentado	a	seguir.
<div	style="text-align:center">
		<h1>
				Welcome	to	{{	title	}}!
		</h1>
		<img	width="300"	alt="Angular	Logo"	src="data:image/svg+xml;base64,PHN...Pg==">
</div>
...
Se	HTML	for	familiar	pra	você	então	não	há	problema	para	entender	o	código	do	Template.
Na	verdade,	tem	algo	diferente	ali	perto	de		Welcome	to		e	vamos	falar	disso	daqui	a	pouco.
Agora,	o	Controller	do	mesmo	componente,	no	arquivo		./src/app/app.component.ts	,	com
código-fonte	a	seguir:
import	{	Component	}	from	'@angular/core';
@Component({
		selector:	'app-root',
		templateUrl:	'./app.component.html',
		styleUrls:	['./app.component.css']
})
export	class	AppComponent	{
		title	=	'app';
}
Há	pouco	conteúdo,	mas	já	são	usados	vários	conceitos	do	Angular,	vamos	examinar	um-a-
um:
1.	 a	primeira	linha	usa	a	instrução		import		para	incluir	algo	chamado		Component		e	que	é
disponibilizado	pelo	pacote		@angular/core	.
2.	 	Component		é	uma	annotation	function	e	é	utilizada	pelo	Angular	para	adicionar
metadados	à	classe		AppComponent	.
3.	 Os	metadados	são	fornecidos	como	parâmetro	para	a	função		Component	:
i.	 	selector	:	indica	que	o	seletor	é		app-root	.	E	o	que	é	seletor?	Veremos	daqui	a
pouco
ii.	 	templateUrl	:	indica	que	o	arquivo	utilizado	para	o	template	do	componente	é
	./app.component.html		(que	vimos	há	pouco)
Criando	o	projeto
22
iii.	 	styleUrls	:	é	um	array	que	indica	quais	são	os	arquivos	CSS	utilizados	no
componente.	Nesse	caso,	está	sendo	utilizado	apenas	o	arquivo
	./app.component.css	
4.	 a	instrução		export		é	utilizada	para	que	outros	arquivos	possam	utilizar	a	classe
	AppComponent	
Antes	de	prosseguirmos,	perceba	que	há	um	atributo	da	classe		AppComponent		chamado
	title		e	tem	o	valor		'app'		(onde	já	vimos	isso?).
A	figura	a	seguir	ilustra	a	estrutura	do		AppComponent	.
Figura	2.4.2	-	Estrutura	do	component	AppComponent
Como	mostra	a	figura	o	componente		AppComponent		é	composto	por	Template,	Controller	e
Model.	O	Template	está	definido	no	arquivo		./src/app/app.component.html	,	enquanto	o
Controller	e	o	Model	estão	definidos	no	arquivo		./src/app/app.component.ts	.	Template	e
Controller	são	mais	fáceis	de	identificar	nessa	arquitetura.	Enquanto	o	primeiro	está	no
arquivo	HTML	o	segundo	é	a	classe	no	arquivo	TypeScript.	Entretanto,	onde	está	o	Model?
Antes	de	responder	essa	pergunta	faça	um	alteração	no	Controller:	altere	o	valor	do	atributo
	title		para,	por	exemplo,		'Angular'	.
Se	você	não	tiver	interrompido	a	execução	do	script		npm	start		acontecerá	uma
recompilação	incremental	automaticamente	e	a	janela	do	Browser	será	recarregada.	Na
página,	o	que	está	logo	depois	de		Welcome	to		?	Isso	mesmo,	a	palavra	"Angular".	Que
mágica	é	essa?	Nenhuma	mágica!	Veja	novamente	o	Template,	mais	de	perto:
<h1>
Welcome	to	{{	title	}}!
</h1>
Criando	o	projeto
23
Nesse	momento	você	já	deve	ter	aprendido	que	o	trecho		{{	title	}}		é	responsável	por
fazer	com	que	o	valor	do	atributo		title		to	Controller	apareça	no	Browser.	Isso	é	resultado
do	processo	de	Data	binding:
analisa	o	Controller	e	identifica	métodos	e	atributos
interpreta	e	analisa	o	Template	e	procura	por,	por	exemplo,	conteúdo	que	esteja	entre
	{{		e		}}	
utiliza	o	recurso	de	interpolação,	que	faz	com	a	expressão	dentro	de		{{		e		}}		seja
interpretada	e	gere	uma	alteração	no	conteúdo	do	Template	ao	ser	apresentado	no
Browser.	Nesse	caso		{{	title	}}		significa:	mostre	o	valor	de		title	.
A	figura	a	seguir	ilustra	os	elementos	desse	processo.
Figura	2.4.3	-	Relação	entre	Model-Template-Controller	no	AppComponent
Aqui	aprendemos	algo	um	conceito	importante:	o	Angular	interpreta	o	Template.	Isso
significa	que	todo	o	seu	conteúdo,	HTML	e	CSS,	é	interpretado	pelo	Angular	antes	de	ser
entregue	para	o	Browser.	É	isso	que	faz	com	que	o	recurso	de	interpolação	funcione.	É	por
isso,	também,	que	Data	binding	é	tão	importante	no	Angular.	Ele	é	responsável	por	fazer
com	que	o	atributo		title	,	que	compõe	o	Model	(ah,	agora	sim!),	esteja	disponível	para	ser
usado	no	Template.	Além	disso,	qualquer	alteração	no	valor	desse	atributo	representará
uma	alteração	na	visualização	do	componente	no	Browser.
Se	você	se	lembrar	da	discussão	sobreAngular	ser	MVC	ou	MVVM	é	aqui	que	o
entendimento	pesa	a	favor	do	segundo.	O	Controller	não	está	desassociado	do	Model	e,
por	causa	do	Data	binding,	sua	função	inclui	informar	o	Template	de	que	ocorreu	uma
alteração	no	Model,	de	forma	que	ele	seja	atualizado.
Criando	o	projeto
24
É	isso,	o	Model	é	um	conceito	abstrato	e	está,	geralmente,	no	Controller,	representado	por
atributos	e	métodos	--	sim,	também	é	possível	mostrar	o	valor	retornado	por	um	método	no
template	(mais	sobre	isso	depois).
Para	finalizar	essa	seção	falta	entender	como	o		AppComponent		é	apresentado	e	qual	a
relação	dele	com	o		AppModule		ou	outros	componentes	do	projeto.	Para	isso,	veja	o	arquivo
	./src/index.html	:
<!doctype	html>
<html	lang="en">
<head>
		<meta	charset="utf-8">
		<title>Angular	Escola</title>
		<base	href="/">
		<meta	name="viewport"	content="width=device-width,	initial-scale=1">
		<link	rel="icon"	type="image/x-icon"	href="favicon.ico">
</head>
<body>
		<app-root></app-root>
</body>
</html>
Ele	é	o	primeiro	arquivo	que	o	Browser	acessa,	embora	não	somente	com	esse	conteúdo.
Quando	o	Angular	compila	o	código-fonte	ele	entrega	um	pouco	mais,	veja:
<!doctype	html>
<html	lang="en">
...
</head>
<body>
		<app-root></app-root>
		<script	type="text/javascript"	src="inline.bundle.js"></script>
		<script	type="text/javascript"	src="polyfills.bundle.js"></script>
		<script	type="text/javascript"	src="styles.bundle.js"></script>
		<script	type="text/javascript"	src="vendor.bundle.js"></script>
		<script	type="text/javascript"	src="main.bundle.js"></script>
</body>
</html>
Esse	é	um	trecho	do	código-fonte	visualizado	pelo	Browser.	Perceba	as	linhas	com
elementos		script		antes	da	tag		</body>	.	Esses	elementos	não	estão	no	código-fonte
original,	eles	foram	embutidos	aí	pelo	processo	de	compilação	do	Angular	(que	foi	iniciado
quando	o	script		npm	start		foi	executado).	Não	precisa	fazer	isso	agora	(sério!)	mas	em
algum	momento	você	vai	perceber	que	o	conteúdo	daqueles	arquivos	indicados	nos
elementos		script		é	realmente	muito	importante	porque	eles	representam	o	resultado	da
Criando	o	projeto
25
tradução	de	todo	o	código-fonte	do	projeto	em	conteúdo	que	o	Browser	consegue
interpretar.	Destaque	para	o	arquivo		main.bundle.js	,	que	contém	o	conteúdo	do	arquivo
	./src/main.ts		cujo	trecho	é:
import	{	enableProdMode	}	from	'@angular/core';
import	{	platformBrowserDynamic	}	from	'@angular/platform-browser-dynamic';
import	{	AppModule	}	from	'./app/app.module';
...
platformBrowserDynamic().bootstrapModule(AppModule)
		.catch(err	=>	console.log(err));
O	método		platformBrowserDynamic()		retorna	um	objeto	que	contém	o	método
	boostrapModule()		que,	ao	ser	executado,	recebe	como	parâmetro	a	classe		AppModule	,	que
será	utilizada	para	representar	o	root	module.	Lembra	disso?	No	capítulo	Iniciando	com	o
Angular	vimos	que	o	root	module	é	o	módulo	mais	importante	de	todo	projeto	Angular,
porque	é	o	primeiro	a	ser	executado	(agora	você	deve	estar	entendendo	isso).
Certo,	então	o	Angular	carrega	primeiro	o		index.html	,	depois	usa	o		AppModule		como	root
module,	mas	isso	ainda	não	explica	como	o		AppComponent		passou	a	aparecer	no	Browser.
Para	entender	isso,	veja	o	arquivo		./src/app/app.module.ts	,	que	define	o		AppModule	:
import	{	BrowserModule	}	from	'@angular/platform-browser';
import	{	NgModule	}	from	'@angular/core';
import	{	AppComponent	}	from	'./app.component';
@NgModule({
		declarations:	[
				AppComponent
		],
		imports:	[
				BrowserModule
		],
		providers:	[],
		bootstrap:	[AppComponent]
})
export	class	AppModule	{	}
As	três	primeiras	linhas	importam	os	módulos		BrowserModule		e		NgModule		dos	seus
respectivos	pacotes,	bem	como	a	classe		AppComponent	.	Como	você	já	sabe,	o	Angular
utiliza	annotation	functions	para	adicionar	metadados	a	classes.	Aqui	está	sendo	utilizada
a	função		NgModule()		que	transforma	a	classe		AppModule		em	um	módulo	para	o	Angular.	O
objeto	passado	como	parâmetro	para	a	função	possui	características	importantes	a
destacar:
	declarations	:	é	um	vetor	que	contém	componentes	do	módulo	(isso	mesmo,
Criando	o	projeto
26
	AppComponent		está	contido	no		AppModule	);
	imports	:	é	um	vetor	que	contém	as	dependências	(outros	módulos);
	bootstrap	:	é	um	vetor	que	contém	os	componentes	que	devem	ser	utilizados	quando
uma	instância	do		AppModule		passar	a	existir	(isso,	indicado	ali	no	arquivo
	./src/main.ts	).
As	coisas	estão	ficando	mais	conectadas	agora	e	a	figura	a	seguir	ilustra	isso.
É	isso!	O	elemento		app-root		é	interpretado	corretamente	pelo	Browser	quando	recebe	o
arquivo		index.html		porque	ele	está	indicado	como		selector		do		AppComponent	,	que	é	o
componente	executado	pelo		AppModule	,	qué	o	root	module.	O		selector		do		AppComponent	
é	utilizado	pelo	Angular	para	saber	onde	apresentar	o	component	no	Template.	O	valor
	'app-root'		indica	que	o	Angular	deve	procurar	um	elemento	com	esse	nome.	E	é	o	que
acontece.
Viu?	Não	é	mágica.	É	software!
O	que	vem	a	seguir?
Como	agora	você	já	deve	estar	entendendo	melhor	o	funcionamento	do	Angular	e	o	código-
fonte	do	projeto,	é	hora	de	sujar	as	mãos	=)	No	capítulo	a	seguir	você	vai	implementar	o
requisito:	ver	as	disciplinas.
Criando	o	projeto
27
Depurando	código	no	browser
[info]	Objetivos	do	capítulo:
demonstrar	como	utilizar	o	recurso	de	depuração	de	código	do	Browser
Branch:	iniciando
Devido	ao	processo	de	compilação/tradução	do	código-fonte	para	que	o	browser	execute	o
software	os	recursos	de	inspeção	do	código-fonte/elementos	apresenta	o	que	o	browser
interpreta,	ou	seja,	o	resultado	do	processo	de	compilação/tradução.	A	figura	a	seguir	ilustra
a	tela	de	um	browser	com	o	painel	das	ferramentas	de	desenvolvedor.
Enquanto	isso	é	útil	para	o	browser,	não	permite	que	o	desenvolver	possa	acompanhar	a
execução	de	partes	do	software	observando	o	código-fonte	original.
Entretanto,	a	mesma	ferramenta	dá	acesso	à	importante	funcionalidade	de	depuração	de
código.	Para	isso,	basta	acessar	o	painel	Sources	e,	na	aba	Network,	à	esquerda,	acessar
o	nó		webpack://		e	seu	filho	que	corresponde	ao	caminho	do	projeto	do	software	no
ambiente	local	(ex:		D:/developer/angular-escola	),	como	mostra	a	figura	a	seguir.
Depurando	código	no	browser
28
https://github.com/jacksongomesbr/angular-escola/tree/iniciando
A	figura	demonstra	que	o	arquivo		/src/app/app.component.ts		está	selecionado.	Do	lado
direito	da	lista	dos	arquivos	a	tela	apresenta	o	código-fonte	original	do	arquivo.	No	painel
que	mostra	o	código-fonte	há	um	breakpoint	(ponto	de	parada)	na	linha	9.	Isso	significa
que	a	execução	do	software	no	browser	terá	uma	pausa	quando	da	sua	execução.	Ainda
mais	à	direita	da	tela	há	uma	barra	de	ferramentas	que	permitem	controlar	a	depuração:
Os	botões	representam,	nesta	ordem:
pausar/continuar	a	execução	do	código
executar	a	próxima	linha	e	não	entrar	no	código	da	função/método
executar	a	próxima	linha	e	entrar	no	código	da	função/método
executar	a	próxima	linha	e	sair	do	código	da	função/método
desativar	os	breakpoints
pausar	em	exceções
A	figura	a	seguir	ilustra	a	tela	durante	o	processo	de	depuração.
Depurando	código	no	browser
29
Por	fim,	no	painel	mais	à	direita	é	possível	acessar	funcionalidades	como	inspecionar
variáveis	ou	expressões	(Watch),	ver	a	pilha	de	chamadas	(Call	stack)	e	inspecionar	as
variáveis	do	escopo	(Scope).
Depurando	código	no	browser
30
Iniciando	com	teste	de	software
[info]	Objetivos	do	capítulo:
apresentar	o	conceito	de	teste	de	software
demonstrar	como	escrever	testes	com	o	Angular	utilizando	Karma	e	Jasmine
Branch:	iniciando
Teste	de	software	é	uma	área	da	Engenharia	de	Software	que	envolve	um	conjunto	de
práticas	para	garantir	a	qualidade	de	software	conforme	requisitos	e	expectativas	dos
interessados,	clientes	ou	desenvolvedores.	Durante	esse	processo	há	geração	de
informação	e	conhecimento	que	permite	entender	o	comportamento	do	software	em
situações	simuladas	ou	com	dados	fictícios.
Uma	forma	de	avaliar	a	qualidade	do	software	utilizando	testede	software	é	utilizar
mecanismos	que	permitam	identificar	se	o	software	está	operando	como	esperado,	fazendo
o	que	deveria	fazer.
Ao	criar	o	projeto	com	o	Angular	CLI,	junto	com	o	componente		AppComponent		também	é
criado	o	arquivo		src/app/app.component.spec.ts	.	Esse	arquivo	TypeScript	descreve	testes
utilizando	Jasmine.	Por	definição	Jasmine	é	um	framework	de	teste	de	software	que	segue
a	técnica	BDD	(Behaviour	Driven	Development).	Embora	o	Jasmine	possa	ser	utilizado
diretamente	para	testar	JavaScript	o	Angular	utiliza	duas	outras	tecnologias:
Karma,	uma	ferramenta	utilizada	para	executar	os	testes	escritos	em	Jasmine	(por
definição,	Karma	é	um	test	runner);	e
Protractor,	um	framework	para	testes	end-to-end	(e2e).
Então,	um	trecho	do	arquivo		src/app/app.component.spec.ts	:
Iniciando	com	teste	de	software
31
https://github.com/jacksongomesbr/angular-escola/tree/iniciando
https://jasmine.github.io/index.html
https://karma-runner.github.io/1.0/index.html
http://www.protractortest.org
import	{	TestBed,	async	}	from	'@angular/core/testing';
import	{	AppComponent	}	from	'./app.component';
describe('AppComponent',	()	=>	{
		...
		}));
		it('should	create	the	app',	async(()	=>	{
		...
		}));
		it(`should	have	as	title	'Angular'`,	async(()	=>	{
		...
		}));
		it('should	render	title	in	a	h1	tag',	async(()	=>	{
		...
		}));
});
Testes	escritos	em	Jasmine	são	chamados	de	specs	e,	por	padrão,	precisam	estar	em
arquivos	com	nomes	que	terminem	em		.spec.ts		(isso	está	definido	no	arquivo
	src/tsconfig.spec.json	).
Depois	das	primeiras	linhas	com	import	há	a	primeira	utilização	de	um	recurso	do	Jasmine:
a	chamada	do	método		describe()	.	Esse	método	cria	uma	suíte	de	testes	(um	grupo	de
testes).	Os	parâmetros	para	o	método	são:
o	nome	da	suíte	de	testes;	e
uma	função	que	define	suítes	internas	e	specs.
No	exemplo,	o	nome	da	suíte	é	'AppComponent'	e	a	função	que	define	as	suítes	internas	e
as	specs	está	definindo	três	testes.
As	specs	(testes)	são	definidas	por	meio	de	uma	chamada	ao	método	it().	Esse	método	cria
uma	spec.	Os	parâmetros	do	método	são:
o	nome	da	spec	(na	prática,	uma	descrição	do	que	a	spec	está	testando);
uma	função	que	descreve	o	código	do	teste;	e
um	número	que	representa	o	tempo	limite	de	execução	do	teste	(timeout).
No	caso	do	exemplo	há	três	specs:
	should	create	the	app		(deveria	criar	o	app	--	ou	o	app	deveria	ser	criado)
	should	have	title	as	'Angular'		(deveria	ter	o	título	como	'Angular'	--	ou	o	título
deveria	ser	'Angular')
	should	render	title	in	a	h1	tag		(deveria	renderizar	o	título	em	uma	tag	h1	--	ou	o
título	deveria	estar	em	uma	tag	h1)
Iniciando	com	teste	de	software
32
Percebeu	o	"should"	(deveria)	no	nome	de	cada	spec?	Isso	faz	parte	da	filosofia	BDD	que
indica	que	cada	spec	checa	se	as	expectativas	sobre	o	teste	são	válidas	(passam)	ou	não
(falham).	Antes	de	ver	mais	detalhes,	vamos	testar	o	software.	Execute	o	comando:
npm	test
Esse	comando	executa	o	script	"test"	definido	no	arquivo		package.json	.	Na	prática,	ele
executa	o	comando		ng	test	.
Dentro	de	instantes	você	deveria	ver	uma	janela	do	browser	mostrando	algo	semelhante	ao
da	figura	a	seguir.
Figura	2.6.1	-	Janela	do	browser	demonstrando	o	resultado	dos	testes	iniciais
Note	que	a	URL	do	browser	é		http://localhost:9876	.	Essa	é	a	URL	padrão	que	apresenta
os	resultados	do	teste	do	software.	A	tela	apresenta	várias	informações	importantes:
versão	do	sistema	operacional	(Windows	10)
Iniciando	com	teste	de	software
33
versão	do	browser	(Chrome	63)
versão	do	Karma	(1.7.1)
versão	do	Jasmine	(2.6.4)
tempo	total	de	execução	dos	testes	(0.187s)
quantidade	de	specs	(3)
quantidade	de	falhas	é	zero	(0),	o	que	indica	que	todos	os	testes	passaram	(ou	que
não	houve	falha	nos	testes)
Além	disso	a	tela	apresenta	o	próprio	componente	(	AppComponent	)	em	execução.	Ainda,
também	há	informações	no	prompt.	Você	deveria	ver	algo	como	o	seguinte:
15	12	2017	01:56:31.937:WARN	[karma]:	No	captured	browser,	open	http://localhost:9876/
15	12	2017	01:56:32.381:INFO	[Chrome	63.0.3239	(Windows	10	0.0.0)]:	Connected	on	socke
t	...
Chrome	63.0.3239	(Windows	10	0.0.0):	Executed	0	of	3	SUCCESS	(0	secs	/	0	secs)
Chrome	63.0.3239	(Windows	10	0.0.0):	Executed	1	of	3	SUCCESS	(0	secs	/	0.101	secs)
Chrome	63.0.3239	(Windows	10	0.0.0):	Executed	2	of	3	SUCCESS	(0	secs	/	0.143	secs)
Chrome	63.0.3239	(Windows	10	0.0.0):	Executed	3	of	3	SUCCESS	(0	secs	/	0.184	secs)
Chrome	63.0.3239	(Windows	10	0.0.0):	Executed	3	of	3	SUCCESS	(0.092	secs	/	0.184	secs)
Essas	informações	indicam	dados	adicionais:
o	primeiro	teste	executou	em	0.101s
o	segundo	teste	executou	em	0.143	-	0.101	=	0.042s
o	terceiro	teste	executou	em	0.184	-	0.143	=	0.041s
Ok,	agora	vamos	a	detalhes	dos	testes	mas,	antes	de	ver	cada	teste	individualmente,	o
segundo	parâmetro	do	método		describe()		chama	o	método		beforeEach()	,	que	é	utilizada
para	realizar	uma	espécie	de	setup	dos	testes,	executando	um	código	antes	deles:
import	{	TestBed,	async	}	from	'@angular/core/testing';
import	{	AppComponent	}	from	'./app.component';
describe('AppComponent',	()	=>	{
		beforeEach(async(()	=>	{
				TestBed.configureTestingModule({
						declarations:	[
								AppComponent
						],
				}).compileComponents();
		}));
		...
A	classe		TestBed		é	um	utilitário	do	Angular	para	testes	de	software.	Seu	método
	configureTestingModule()		cria	um	módulo	específico	para	executar	os	testes	que	serão
descritos	a	seguir.	Pense	nisso	como	um	módulo	mais	enxuto	que	os	utilizados	no	restante
Iniciando	com	teste	de	software
34
do	software,	voltando	apenas	para	esses	testes.	Por	isso	você	deveria	entender	que	o
parâmetro	fornecido	para	o	método	é	muito	similar	aos	metadados	de	um	módulo	e,	nesse
caso,	indicam	os	componentes	do	módulo	(atributo		declarations	).	Portanto,	o	setup
permite	que	cada	teste	utilize	o	componente		AppComponent	.
Primeiro	teste
O	trecho	de	código	a	seguir	apresenta	o	primeiro	teste.
it('should	create	the	app',	async(()	=>	{
		const	fixture	=	TestBed.createComponent(AppComponent);
		const	app	=	fixture.debugElement.componentInstance;
		expect(app).toBeTruthy();
}));
Esse	primeiro	teste	verifica	se	foi	possível	criar	uma	instância	do	componente
	AppComponent	,	o	que	é	feito	por	meio	de	uma	sequência	de	passos:
1.	 criar	uma	instância	de		AppComponent	:	isso	é	feito	por	meio	do	método
	TestBed.createComponent()		(armazenado	na	variável		fixture	)	que	retorna	uma
instância	de		ComponentFixture	,	referência	ao	ambiente	de	execução	dos	testes.	O
ambiente	de	execução	dos	testes	dá	acesso	ao		DebugElement	,	que	representa	o
elemento	do	DOM	que	representa	o	componente
2.	 acessar	a	instância	do	componente	(	fixture.debugElement.componentInstance	),
armazenada	na	variável		app	;
3.	 criar	uma	expectativa	para	o	teste
Uma	expectativa	é	criada	por	meio	do	método		expect()	.	Uma	expectativa	representa	o
comportamento	esperado	do	software:	que		app		(uma	instância	do		AppComponent	)	não	seja
	null	.	O	parâmetro	de		expect()		indica	a	expressão	que	será	analisada,	comparada,	com
outra	expressão	ou	valor.	Nesse	caso	a	comparação	é	realizada	por	meio	do	método
	toBeTruthy()	.	Se	a	expectativa	não	for	satisfeita	o	teste	falhará.	Isso	seria	o
comportamento	obtido,	por	exemplo,	por	causa	de	um	erro	de	tempo	de	execução
(runtime).
Segundo	teste
O	trecho	de	código	a	seguir	apresenta	o	segundo	teste.
Iniciando	com	teste	de	software
35
it(`should	have	as	title	'Angular'`,	async(()	=>	{
		const	fixture	=	TestBed.createComponent(AppComponent);
		const	app	=	fixture.debugElement.componentInstance;
		expect(app.title).toEqual('Angular');
}));
A	sequência	de	passos	é	semelhante	à	do	primeiro	teste.	A	diferença	está	na	expectativa:	o
teste	deseja	verificar	se	o	atributo		title		da	instância	do		AppComponent		(	app	)	tem	valor
igual	a		'Angular'	.	Novamente,	a	expectativa	é	criada	por	meio	do	método		expect()	.
Dessa	vez	a	comparação	entre	o	valor	esperado	(	app.title	)	e	o	valor	obtido	(	'Angular'	)
é	feita	por	meio	do	método		toEqual().
Com	isso	aprendemos	que	é	possível	testar	membros	de	um	componente	(atributos	e
métodos),	o	que	é	muito	valioso.
Terceiro	teste
O	trecho	de	código	a	seguir	apresenta	o	terceiro	teste.
it('should	render	title	in	a	h1	tag',	async(()	=>	{
		const	fixture	=	TestBed.createComponent(AppComponent);
		fixture.detectChanges();
		const	compiled	=	fixture.debugElement.nativeElement;
		expect(compiled.querySelector('h1').textContent).toContain('Welcome	to	Angular!');
}));
Em	relação	aos	testes	anteriores	a	sequência	de	passos	inclui	uma	chamada	ao	método
	ComponentFixture.detectChanges()	.	Você	deveria	aprender,	nos	capítulos	seguintes,	que	o
Angular	utiliza,	muito,	um	recurso	chamado	data	binding.	Esse	recurso	faz	com	que	o	valor
do	atributo		title		seja	apresentado	no	Template.	Para	checar	se	esse	é	o	comportamento
obtido	é	necessário,	primeiro,	identificar	que	ocorreu	data	binding.	Uma	forma	de	fazer	isso
é	usando	o	método		detectChanges()	.
Outra	diferença	é	que	o	teste	lida	com	o	DOM	depois	de	ter	sido	transformado	pelo	Angular,
ou	seja,	na	prática,	em	como	o	usuário	está	vendo	o	componente	no	momento.	Por	causa
disso	não	é	utilizada	uma	instância	do	componente,	mas	uma	referência	ao	DOM	compilado
(o	elemento	DOM	na	raiz	do	componente,	na	verdade).	Isso	é	feito	por	meio	de
	fixture.debugElement.nativeElement		(armazenado	na	variável		compiled	).
Por	fim,	a	expectativa	é	um	pouco	mais	complexa,	pois	envolve	lidar	com	o	DOM.	Para	isso
ocorre	o	seguinte:
1.	 encontrar	o	elemento		h1		no	DOM:	isso	é	feito	por	meio	do	método		querySelector()	;
Iniciando	com	teste	de	software
36
2.	 comparar	o	conteúdo	textual	do	elemento		h1		com	a	string		Welcome	to	Angular!	:	isso
é	feito	por	meio	de	uma	expectativa	sobre	o	valor	do	atributo		textConent		do	objeto	que
representa	o	elemento		h1		conter	a	string	desejada,	comparação	implementada	pelo
método		toContain()	.
You	shall	not	pass!	Ou	provocando	uma	falha
nos	testes
Suponha	que	você	modifique	o	valor	do	atributo		title		do		AppComponent		para		'Web'	.	O
que	os	testes	diriam?	Se	os	testes	ainda	estiverem	em	execução,	apenas	observe	a	janela
do	browser	que	mostra	o	resultado	dos	testes	(ilustrada	pela	figura	a	seguir).
Iniciando	com	teste	de	software
37
A	saída	dos	testes	mostra	claramente	que	algo	errado	aconteceu:	dos	três	testes,	dois
falharam.	A	saída	indica	cada	teste	que	falhou	(detalhe	em	vermelho):
o	segundo	teste	falhou	porque	a	string		'Web'		não	igual	a		'Angular'	;	e
o	terceiro	teste	falhou	porque	a	string		'Welcome	to	Web!'		não	contém		'Welcome	to
Angular!'	.
Percebeu	que	os	testes	são	executados	novamente	sempre	que	há	uma	mudança	no
código	do	software?	Esse	é	o	comportamento	padrão,	mas	se	você	precisar	desligá-lo
precisará	de	uma	mudança	no	arquivo		package.json	,	modificando	o	script	de	teste	de	(	ng
test	):
...
"scripts":	{
...
		"test":	"ng	test",
...
},
...
para	(	ng	test	--single-run	):
...
"scripts":	{
...
		"test":	"ng	test	--single-run",
...
},
...
O	problema	disso	é	que,	ao	executar	o	comando		npm	test		você	verá	a	janela	do	browser
aparecer	e	sumir	logo	depois	de	alguns	instantes.	Assim,	precisará	lidar	com	a	saída	do
comando	no	prompt	para	identificar	o	que	ocorreu	(testes	passaram	ou	falharam).
Iniciando	com	teste	de	software
38
[info]	Resumo	do	capítulo:
testes	de	software	permitem	avaliar	se	o	comportamento	do	software	está	como	o
esperado
Jasmine	é	um	framework	utilizado	para	escrever	testes	usando	a	técnica	BDD
Karma	e	Protractor	são	ferramentas	do	Angular	para	executar	testes
o	comando		npm	test		é	usado	para	executar	testes
testes	são	definidos	dentro	de	suítes
uma	suíte	é	criada	usando	o	método		describe()	
um	teste	é	criado	usando	o	método		it()	
um	teste	pode	validar	diversos	comportamentos	do	software,	mas	cada
comportamento	é	validado	usando	o	método		expect()	,	que	compara	um	valor
esperado	com	um	valor	obtido
testes	do	Angular	envolvem	verificar	membros	do	componente	(atributos	e
método)	e	o	DOM	compilado,	que	é	visualizado	pelo	cliente	no	browser
Iniciando	com	teste	de	software
39
Apresentando	a	lista	de	disciplinas
[info]	Objetivos	do	capítulo:
demonstrar	a	implementação	do	requisito	"apresentar	as	disciplinas"	de	forma
iterativa
demonstrar	o	uso	das	diretivas		ngFor		e		ngIf	
reforçar	o	entendimento	do	Data	binding
Branches:	livro-listando-disciplinas,	livro-listando-disciplinas-objetos,	livro-listando-
disciplinas-classes,	livro-listando-disciplinas-interacao
Começando	pelo	Controller	do		AppComponent	,	remova	o	atributo		title		e	adicione	o
atributo		disciplinas	.	Esse	atributo	é	um	array	de	string,	contendo	os	nomes	das
disciplinas.	O	conteúdo	do	Controller	deve	ficar	mais	ou	menos	assim	(trecho):
export	class	AppComponent	{
		disciplinas	=	[
				'Língua	Portuguesa',
				'Arte',
				'Educação	Física',
				'Matemática',
				'História',
				'Geografia',
				'Ciências',
				'Redação',
				'Língua	Estrangeira	Moderna	-	Inglês',
				'Ensino	Religioso'
		];
}
Na	sequência	altere	o	Template	do		AppComponent		para	o	seguinte	conteúdo:
<h1>Disciplinas</h1>
<hr>
<ul>
		<li	*ngFor="let	disciplina	of	disciplinas">
				{{disciplina}}
		</li>
</ul>
Parte	importante	do	Template	está	no	elemento		li	:	o	atributo		*ngFor		é,	na	verdade,	uma
diretiva	estrutural	que	modifica	o	Template	no	browser,	gerando	novos	elementos	com
base	em	uma	repetição.
Apresentando	a	lista	de	disciplinas
40
https://github.com/jacksongomesbr/angular-escola/tree/livro-listando-disciplinas
https://github.com/jacksongomesbr/angular-escola/tree/livro-listando-disciplinas-objetos
https://github.com/jacksongomesbr/angular-escola/tree/livro-listando-disciplinas-classes
https://github.com/jacksongomesbr/angular-escola/tree/livro-listando-disciplinas-interacao
A	diretiva,	na	verdade	mesmo,	é	chamada		NgForOf	.	Usamos	uma	espécie	de	atalho
por	meio	do	atributo		*ngFor		(sem	mais	explicações	sobre	isso,	por	enquanto).	Então,
ao	ler		NgForOf		ou		*ngFor		saiba	que	estamos	falando	da	mesma	coisa.
A	diretiva		*ngFor		é	utilizada	para	repetir	um	elemento	do	Template.	Nesse	caso,	é
justamente	essa	a	sua	aplicação:	repetir	o	elemento		li		para	apresentar	os	nomes	das
disciplinas.	A	repetição	é	realizada	por	uma	expressão:		let	disciplina	of	disciplinas	
significa	que	o		*ngFor		vai	repetir	o	elemento		li		para	cada	item	do	array		disciplinas		e
cada	item	recebe	o	nome	de		disciplina	,	o	que	demonstra	outra	utilização	do	Data
binding.	Explicando	a	mesma	coisa	de	outra	forma:
a	repetição	sempre	é	baseada	em	uma	coleção	de	itens	(ou	em	algo	que	possa	ser
interpretado	como	tal)
o	Angular	cria	uma	variável	de	template	(existe	apenas	dentro	do	elemento		li	)	com	o
nome	de		disciplina	
essa	variável	de	template	é	usada	como	uma	referência	para	cada	item	da	repetição
É	por	isso	que	a	interpolação	funciona	dentro	do	elemento		li		para	apresentar	o	nome	de
cada	disciplina.
A	documentação	do	Angular	afirma	que		let	disciplina	of	disciplinas		é	uma
microssintaxe	e	isso	não	é	a	mesma	coisa	que	uma	expressão	usada	em	uma
interpolação.
Abra	o	aplicativo	no	browser.	O	resultado	deve	ser	semelhante	à	figura	a	seguir.
Apresentando	a	lista	de	disciplinas
41
Figura	2.7.1	-	Apresentando	a	lista	das	disciplinas
Melhorando	o	modelo	de	dados	usando
objetos
A	utilização	de	um	array	de	strings	pode	ser	suficiente	em	vários	casos.	Entretanto,	quando
se	deseja	apresentar	mais	informações	é	necessário	utilizar	outra	abordagem.	Suponha,
portanto,	que	precisemos	apresentar	dois	dados	de	cada	disciplina:	nome	e	descrição.
Uma	boa	forma	de	fazer	isso	é	utilizar	objetos.
Modifique	o	Controller	do		AppComponent		para	que	cada	item	do	array		disciplinas		seja	um
objeto	com	dois	atributos:		nome		e		descricao	,	como	mostra	o	trecho	de	código	a	seguir.
Apresentando	a	lista	de	disciplinas
42
...
export	class	AppComponent	{
		disciplinas	=	[
				{
						nome:	'Língua	Portuguesa',
						descricao:	'O	objetivo	norteador	da	BNCC	de	Língua	Portuguesa	é	'	+
						'garantir	a	todos	os	alunos	o	acesso	aos	saberes	'+
						'linguísticos	necessários	para	a	participação	social	e	o	exercício	'	+
						'da	cidadania,	pois	é	por	meio	da	língua	que	'	+
						'o	ser	humano	pensa,	comunica-se,	tem	acesso	à	informação,	expressa	'	+
						'e	defende	pontos	de	vista,	partilha	ou	'	+
						'constrói	visões	de	mundo	e	produz	conhecimento.'
				},
				...
		];
}
Essa	notação	do	TypeScript	para	representar	objetos	de	forma	literal	é	muito	útil	quando
não	se	tem	uma	classe	para	descrever	objetos.
Na	sequência	ocorre	uma	pequena	alteração	no	Template:
<h1>Disciplinas</h1>
<hr>
<ul>
		<li	*ngFor="let	disciplina	of	disciplinas">
						<strong>{{disciplina.nome}}</strong>:	{{disciplina.descricao}}
		</li>
</ul>
A	principal	mudança	está	no	fato	de	que	as	interpolações	usam	expressões	baseadas	nos
atributos	do	objeto		disciplina	.
Para	ver	o	resultado,	abra	o	aplicativo	no	browser.
Melhorando	o	modelo	de	dados	usando
classes
Enquanto	a	utilização	de	objetos	literais	é	bastante	útil,	também	é	interessante	expressar	o
modelo	de	dados	utilizando	classes.	Para	isso,	crie	o	arquivo
	./src/app/disciplina.model.ts		com	o	conteúdo	a	seguir:
Apresentando	a	lista	de	disciplinas
43
export	class	Disciplina	{
		nome:	string;
		descricao:	string;
		constructor(nome:	string,	descricao?:	string)	{
				this.nome	=	nome;
				this.descricao	=	descricao;
		}
}
Para	utilizar	mais	recursos	do	TypeScript,	a	classe		Disciplina		possui	dois	atributos:		nome	
e		descricao	,	ambos	do	tipo		string	.	O	método		constructor()		recebe	dois	parâmetros,
ambos	do	tipo		string	:		nome		e		descricao		(que	é	opcional	--	note	o	uso	de		?	).	Para
concluir,	a	classe	é	disponibilizada	para	uso	externo	por	meio	da	instrução		export	.
Para	usar	a	classe		Disciplina	,	modifique	o	Controller	do		AppComponent	:
import	{Component}	from	'@angular/core';
import	{Disciplina}	from	'./disciplina.model';
...
export	class	AppComponent	{
		disciplinas	=	[
				new	Disciplina('Língua	Portuguesa',	'O	objetivo	norteador	...'),
				new	Disciplina('Educação	Física',	'A	Educação	Física	é	...'),
				...
		];
}
Perceba	que	os	elementos	do	atributo		disciplinas		agora	são	instâncias	da	classe
	Disciplina	.	O	mais	interessante	é	que	o	Template	não	precisa	ser	alterado,	já	que	está
utilizando	objetos	com	a	mesma	estrutura	de	antes,	ou	seja,	espera	que	os	itens	do	atributo
	disciplinas		sejam	objetos	que	tenham	os	atributos		nome		e		descricao	.
Adicionando	interação	com	o	usuário
A	apresentação	de	todos	os	dados	das	disciplinas	na	tela	pode	ser	melhorada	usando
interação	com	o	usuário.	Suponha	que	o	usuário	veja	a	lista	das	disciplinas	contendo
apenas	seus	nomes;	ele	deve	clicar	no	nome	de	uma	disciplina	para	ver	sua	descrição.
Além	disso,	para	dar	uma	resposta	visual	para	o	usuário	quando	ele	clicar	no	nome	da
disciplina,	considere	que	será	usada	uma	formatação	em	negrito.
Para	implementar	esses	requisitos	vamos	usar	outros	recursos	do	Angular.
Começando	pelo	Controller	do		AppComponent		são	acrescentados:
Apresentando	a	lista	de	disciplinas
44
o	atributo		selecionado	
o	método		selecionar()	
export	class	AppComponent	{
		selecionado	=	null;
		disciplinas	=	[
				new	Disciplina('Língua	Portuguesa',	'O	objetivo	norteador	da	BNCC	...'),
		...
		];
		selecionar(disciplina)	{
				this.selecionado	=	disciplina;
		}
}
O	atributo		selecionado		será	utilizado	para	que	o	Controller	saiba	qual	disciplina	o	usuário
selecionou.	O	usuário	fará	isso	por	meio	de	uma	chamada	para	o	método		selecionar()	,
que	recebe	o	parâmetro		disciplina		e	o	atribui	para	o	atributo		selecionado	.	Quando	isso
acontecer	(o	usuário	selecionar	uma	disciplina)	o	software	apresentará	a	sua	descrição.
Para	utilizar	mais	recursos	do	desenvolvimento	front-end,	dessa	vez	também	alteramos	o
arquivo		./src/app/app.component.css	:
.selecionado	{
				font-weight:	bold;
}
li	p:nth-child(1)	{
				cursor:	pointer;
				font-size:	12pt;
}
li	p:nth-child(1):hover	{
				font-weight:	bold;
}
li	p:nth-child(2)	{
				font-size:	10pt;
}
O	arquivo	CSS	do		AppComponent		possui	regras	de	formatação:
seletor		.selecionado	:	para	deixar	o	nome	da	disciplina	selecionada	em	negrito
seletor		li	p:nth-child(1)	:	para	que	o	cursor	do	mouse	sobre	o	nome	da	disciplina
seja		pointer		(semelhante	ao	comportamento	do	cursor	em	links)	e	tenha	fonte	de
tamanho	12pt
seletor		li	p:nth-child(1):hover	:	para	que	o	nome	da	disciplina	sob	o	mouse	fique	em
Apresentando	a	lista	de	disciplinas
45
negrito
seletor		li	p:nth-child(2)	:	para	que	a	fonte	da	descrição	seja	de	tamanho	10pt
Agora,	o	Template:
<h1>Disciplinas</h1>
<hr>
<ul>
		<li	*ngFor="let	disciplina	of	disciplinas"	(click)="selecionar(disciplina)">
						<p	[class.selecionado]="selecionado	==	disciplina">{{disciplina.nome}}</p>
						<p	*ngIf="selecionado	==	disciplina">{{disciplina.descricao}}</p>
		</li>
</ul>
A	primeira	coisa	a	destacar	é	o	recurso	que	proporciona	a	interação	com	o	usuário.	Como	já
comentado,	o	requisito	determina	que	o	usuário	possa	clicar	no	nome	da	disciplina.	Isso	é
um	ação	do	usuário	para	a	interface.	O	Angular	implementa	isso	por	meio	de	eventos	e	de
uma	sintaxe	própria:	o	atributo		(click)		no	elemento		li		indica	que	estamos	fornecendo
um	tratador	para	o	evento		click	;	o	tratador	é	o	valor	do	atributo,	ou	seja,	uma	expressão
que	representa	a	chamada	do	método		selecionar(disciplina)	,	definido	no	Controller.
Outra	característica	importante	é	a	chamada	do	método		selecionar()		fornece	como
parâmetro		disciplina	,	que	é	o	item	da	repetição	realizada	pelo		*ngFor	.	Se	você	voltar	no
código	do	Controller	vai	ver	que	esse	parâmetro	é	atribuído	para	o	atributo		selecionado	,
que	faz	justamente	isso:	guarda	uma	referência	para	a	disciplina	selecionada.
O	próximo	passo	é	garantir	o	determinado	no	requisito	no	sentido	da	apresentação.	Para
fazer	com	que	a	disciplina	selecionada	fique	em	negrito	vamos	aplicar	uma	classe	CSS
chamada		selecionado		em	um	elemento		p		que	contém	o	nome	da	disciplina	sempre	que	a
	disciplina		da	repetição	do		*ngFor		for	igual	à	disciplina	selecionada.	O	Angular	fornece
um	recurso	para	modificar	características	de	elementos	do	HTML	por	meio	de	expressões.
Esse	recurso	está	sendo	usado	na	tag		<p>	:		[class.selecionado]		parece	como	um	atributo
do	HTML,	mas	é	tratado	pelo	Angular	antes	de	o	HTML	ser	fornecido	para	o	browser,
modificando	o	atributo		class		e	inserindo	nele	a	classe	CSS	chamada		selecionado	.	Nesse
sentido,	o	valor	do	atributo	é	uma	expressão	e,	nesse	caso,	uma	expressão	booleana:
	selecionado	==	disciplina		determina,	então,	que	o	elemento		p		terá	o	atributo		class	
com	valor		selecionado		se	a		disciplina		atual	da	iteração	do		*ngFor		for	igual	à	disciplina
selecionada.
Para	finalizar,	o	software	deve	apresentar	a	descrição	da	disciplina	selecionada.	Para	isso
vamos	usar	outra	diretiva,	a		NgIf	.	Veja	o	trecho:
Apresentando	a	lista	de	disciplinas
46
<li	*ngFor="let	disciplina	of	disciplinas"	...>
				...
				<p	*ngIf="selecionado	==	disciplina">{{disciplina.descricao}}</p>
</li>
A	diretiva		*ngIf		é	aplicada	no	elemento		p		usado	para	apresentar	a	descrição	da
disciplina.	Como	o	propósito	dessa	diretiva	é	funcionar	como	um	condicional	o	valor	que	o
atributo	recebe	é	uma	expressão	booleanda:		selecionado	==	disciplina	.	Se	a	expressão
for	verdadeira	(se	a		disciplina		da	repetição	do		*ngFor		for	igual	à	disciplina	selecionada),
o	elemento		p		estará	presente	no	HTML,	caso	contrário,	não	estará	presente.	Perceba	que
usei	o	termo	"estar	presente"	ao	invés	de	"visível"	porque	é	isso	que	acontece.	Se	a
expressão	booleanda	for	falsa,	o	elemento	no	qual	a	diretiva		*ngIf		é	aplicada	nem	está
presente	no	HTML.
Para	ilustrar	isso,	veja	um	trecho	da	estrutura	HTML	no	browser:
<ul	_ngcontent-c0="">
		<!--bindings={"ng-reflect-ng-for-of":	"[object	Object],[object	Object"}-->
		<li	_ngcontent-c0="">
						<p	_ngcontent-c0=""	class="selecionado">Língua	Portuguesa</p>
						<!--bindings={"ng-reflect-ng-if":	"true"}-->
						<p	_ngcontent-c0="">O	objetivonorteador	da	BNCC	de	Língua	Portuguesa	...</p>
		</li>
		<li	_ngcontent-c0="">
						<p	_ngcontent-c0=""	class="">Educação	Física</p>
						<!--bindings={"ng-reflect-ng-if":	"false"}-->
		</li>
		...
</ul>
Os	vários	comentários	presentes	no	HTML	parecem	ser	algo	que	o	Angular	utiliza	para
tratar	o	comportamento	da	interface?	É	justamente	isso	que	acontece	(não	precisa	tentar
interpretar	os	comentários	agora).	No	caso	desse	exemplo,	o	usuário	clicou	na	disciplina
"Língua	Portuguesa".	Características	importantes:
para	o	elemento		li		correspondente	à	disciplina	selecionada:
o	elemento		p		que	mostra	o	nome	da	disciplina	possui		class="selecionado"	
o	elemento		p		que	mostra	a	descrição	da	disciplina	está	presente	no	HTML
para	os	demais	elementos		li	:
o	elemento		p		que	mostra	o	nome	da	disciplina	não	possui	o	atributo		class	
o	elemento		p		que	mostra	a	descrição	da	disciplina	não	existe	no	HTML
Apresentando	a	lista	de	disciplinas
47
Se	você	já	tiver	programado	para	front-end	anteriormente	vai	entender	melhor	a
complexidade	do	que	está	acontecendo	aqui,	que	o	Angular	não	passa	para	o	programador.
O	Angular	está	realizando	a	chamada	manipulação	do	DOM	para	que	o	HTML	entregue
para	o	browser	tenha	o	comportamento	esperado	(ou	explícito	no	software).
Por	fim,	a	figura	a	seguir	ilustra	o	funcionando	do	software	no	browser.
Figura	2.7.2	-	Execução	do	software	no	browser,	listando	disciplinas	e	interagindo	com	o
usuário
Pronto,	esse	capítulo	mostrou	a	utilização	de	vários	recursos	do	Angular	para	implementar
o	requisito	"Apresentar	a	lista	das	disciplinas".
Apresentando	a	lista	de	disciplinas
48
[info]	Para	resumir:
utilizar	recursos	da	Programação	Orientada	a	Objetos	é	muito	bom	para
representação	do	modelo	de	dados
a	diretiva		NgForOf		é	utilizada	para	repetir	elementos	no	Template	com	base	em
uma	coleção	de	itens	(um	array)
a	diretiva		NgIf		é	utilizada	para	incluir	ou	excluir	elementos	do	Template	com	base
em	um	condicional
	(click)		representa	a	sintaxe	do	Angular	para	criar	tratadores	de	eventos
	[class.selecionado]		representa	a	sintaxe	do	Angular	para	adicionar	ou	remover
atributos	no	HTML
Apresentando	a	lista	de	disciplinas
49
Cadastrando	uma	disciplina
[info]	Objetivos	do	capítulo:
demonstrar	o	uso	de	formulários	e	two-way	data	binding
implementar	o	requisito	"Cadastrar	disciplina"
Branches:	livro-cadastrando-disciplina
Neste	capítulo	vamos	começar	pelo	final:	primeiro,	veja	a	figura	que	ilustra	como	o	software
estará	ao	final	do	capítulo.
Figura	2.8.1	-	Tela	do	software	apresentando	a	lista	das	disciplinas	e	o	formulário	de
cadastro
A	tela	do	aplicativo	tem	duas	funções:	na	primeira	parte,	apresenta	a	lista	das	disciplinas;	na
segunda	parte,	apresenta	um	formulário	que	permite	o	cadastro	de	uma	disciplina.	A
primeira	parte	você	já	conhece	do	capítulo	anterior.	Agora,	veremos	os	detalhes	para	o
formulário	de	cadastro.
Cadastrando	uma	disciplina
50
https://github.com/jacksongomesbr/angular-escola/tree/livro-cadastrando-disciplina
Antes	de	prosseguir,	um	fator	importante:	o	projeto	original	criado	pelo	Angular	CLI	não
suporta	formulários.	Isso	mesmo	que	você	leu.	O	Angular	trata	formulários	de	três	formas
diferentes,	uma	delas,	a	que	vamos	utilizar,	chamada	de	template	driven	forms	(algo	como
formuários	orientados	a	templates).
Para	habilitar	o	suporte	a	formulários	é	necessário	importar	o	módulo		FormsModule		no	root
module:
import	{BrowserModule}	from	'@angular/platform-browser';
import	{NgModule}	from	'@angular/core';
import	{FormsModule}	from	'@angular/forms';
import	{AppComponent}	from	'./app.component';
@NgModule({
		...
		imports:	[
				BrowserModule,
				FormsModule
		],
		...
})
export	class	AppModule	{
}
O	módulo		FormsModule		está	definido	no	pacote		@angular/forms		e	é	importado	no
	AppModule		por	meio	do	atributo		imports		dos	metadados	da	classe.	A	partir	de	então	a
utilização	de	formulários	do	tipo	template-driven	forms	está	garantida.
O	formulário	de	cadastro	tem	dois	campos:	nome	e	descrição.	O	comportamento	esperado
pelo	usuário	é	preencher	os	valores	dos	campos,	clicar	no	botão	"Salvar"	e	ver	a	lista	de
disciplinas	atualizada,	contendo	a	disciplina	que	acabou	de	ser	cadastrada.
Para	fazer	isso,	primeiro	vamos	ao	Controller	do		AppComponent	:
Cadastrando	uma	disciplina
51
...
export	class	AppComponent	{
		selecionado	=	null;
		nome	=	null;
		descricao	=	null;
		disciplinas	=	[
				new	Disciplina('Língua	Portuguesa',	'O	objetivo	norteador	da	BNCC	de	...'),
						...
		];
		salvar()	{
				const	d	=	new	Disciplina(this.nome,	this.descricao);
				this.disciplinas.push(d);
				this.nome	=	null;
				this.descricao	=	null;
		}
}
São	adicionados	dois	atributos	e	um	método:
	nome	:	está	ligado	ao	campo	nome	do	formulário	por	meio	de	data	binding
	descricao	:	está	ligado	ao	campo	descricao	do	formulário	por	meio	de	data	binding
	salvar()	:	é	executado	quando	o	usuário	clicar	no	botão	"Salvar"
Os	dois	atributos	são	inciados	com		null	.	O	método		salvar()		cria	uma	instância	da
classe		Disciplina		usando	os	atributos		nome		e		descrição	,	respectivamente.
Posteriormente,	adiciona	esse	objeto	ao	vetor		disciplinas		por	meio	do	método		push()	.
Por	fim,	atribui	o	valor		null		novamente	aos	atributos		nome		e		descricao	.
Mas...	o	que	significa	um	atributo	do	Controller	estar	ligado	a	um	campo	do	formulário	via
data	binding?	Você	já	sabe	que	data	binding	é	o	recurso	do	Angular	que	faz	com	que	o
valor	de	um	atributo	do	Controller	seja	apresentado	no	Template	por	meio	de	interpolação.
E	quanto	ao	formulário?	Vamos	ao	Template:
Cadastrando	uma	disciplina
52
<h1>Disciplinas</h1>
...
<h2>Cadastrar</h2>
<p>Use	este	formulário	para	cadastrar	uma	disciplina.</p>
<form	#cadastro="ngForm"	(submit)="salvar()">
				<div>
								<label	for="nome">Nome</label><br>
								<input	type="text"	id="nome"	name="nome"	[(ngModel)]="nome"	required>
				</div>
				<div>
								<label	for="descricao">Descrição</label><br>
								<textarea	id="descricao"	name="descricao"	[(ngModel)]="descricao"
																		cols="70"	rows="5">
								</textarea>
				</div>
				<button	type="submit"	class="btn	btn-primary"	[disabled]="!cadastro.valid">
								Salvar
				</button>
</form>
Como	a	parte	da	lista	das	disciplinas	não	muda	muito,	vamos	omitir	essa	parte	e	apresentar
o	formulário,	começando	pela	tag		<form>	.	Em	termos	de	HTML,	a	tag	possui	um	atributo
	#cadastro	,	com	valor		ngForm	.	Esse	recurso,	na	verdade,	é	uma	sintaxe	do	Angular	para
criar	uma	variável	(chamada		cadastro	)	vinculada	ao	formulário.	Importante	também
destacar	o	evento		submit	.	Você	já	entende	a	sintaxe		(submit)	,	então	o	tratador	do	evento
é	uma	chamada	ao	método		salvar()	.
Na	sequência	são	definidos	os	campos	do	formulário.	A	parte	mais	importante	está	nas
	tags		input	e		textarea	,	principalmente	o	que,	em	termos	de	HTML,	parece	um	atributo:
	[(ngModel)]	.	Você	já	sabe	a	sintaxe	para	eventos	(entre	parênteses)	e	já	viu	que	o	Angular
consegue	alterar	um	atributo	do	HTML	por	meio	de	colchetes.	Essa	sintaxe,	que	mistura	as
duas	anteriores,	é	a	sintaxe	do	recurso	two-way	data	binding.	No	campo	para	o	nome,
	[(ngModel)]		tem	o	valor		nome	,	para	o	campo	descrição,	tem	o	valor		descricao	.	Ambos
são	atributos	do	Controller.	Assim,	o	two-way	data	binding	significa	que	o	valor	do	atributo
pode	ser	modificado	por	meio	de	uma	alteração	do	campo	de	formulário	correspondente,	e
vice-versa:
se	o	valor	do	atributo		nome		for	modificado	no	Controller,	o	Template	será	atualizado,
mostrando	esse	valor	no		input	
se	o	valor	do	atributo		nome		for	modificado	no	Template,	por	uma	alteração	no		input	,
esse	valor	estará	disponível	no	Controller
Por	isso	o	two-way:	duas	vias.	A	figura	a	seguir	ilustra	esse	processo.
Cadastrando	uma	disciplina
53
Figura	2.8.2	-	Ilustração	do	two-way	data	binding,	ligando	formulário	e	Controller
O	formulário	tem	mais	uma	característica:	a	entrada	do	usuário	está	passando	por
validação.	O	elemento		input		para	o	camponome	tem	o	atributo		required	,	que	o	torna	de
preenchimento	obrigatório.	A	partir	de	então	há	um	comportamento	muito	interessante	para
o	botão	"Salvar":	o	elemento	button	possui	um	atributo		disabled	,	que	é	modificado
conforme	a	expressão		!cadastro.valid	.	Lembra	da	variável	de	template		#cadastro	?	Aqui
ela	é	usada	como	uma	referência	ao	formulário.	Portanto,	se	o	formulário	de	cadastro
estiver	válido,	o	botão	"Salvar"	estará	habilitado	para	clique.	Caso	contrário,	estará
desabilitado.
Execute	o	software	no	browser	para	notar	o	comportamento	citado	no	capítulo.
[info]	Resumo	do	capítulo:
Implementamos	o	requisito	"Cadastrar	uma	disciplina"
Utilizamos	o	recurso	two-way	data	binding
Utilizamos	formulário	para	receber	entrada	do	usuário
Cadastrando	uma	disciplina
54
Excluindo	uma	disciplina
[info]	Objetivos	do	capítulo:
demonstrar	a	implementação	do	requisito	"Excluir	uma	disciplina"
Branch:	livro-excluindo-disciplina
Este	é	um	capítulo	mais	simples.	Basicamente	os	recursos	utilizados	já	foram
apresentados,	então	ele	é	mais	curto.
Primeiro,	um	trecho	do	Controller	do		AppComponent	:
...
export	class	AppComponent	{
		selecionado	=	null;
		nome	=	null;
		descricao	=	null;
		disciplinas	=	[
				new	Disciplina('Língua	Portuguesa',	'...'),
				...
		];
		salvar()	{
		...
		}
		excluir(disciplina)	{
				if	(confirm('Tem	certeza	que	deseja	excluir	a	disciplina	"'
								+	disciplina.nome	+	'"?'))	{
						const	i	=	this.disciplinas.indexOf(disciplina);
						this.disciplinas.splice(i,	1);
				}
		}
}
Com	exceção	do	código	omitido,	que	você	já	conheceu	nos	capítulos	anteriores,	o	método
	excluir()		recebe	como	parâmetro	um	objeto,	chamado		disciplina	.	Esse	método	exclui
uma	disciplina	da	lista,	mas,	antes,	solicita	uma	confirmação	do	usuário	(por	isso	está
usando	a	função		confirm()	).	Se	o	usuário	confirmar	que	deseja	excluir	a	disciplina,	então
o	código	prossegue:
encontra	o	índice	da	disciplina	na	lista	usando	o	método		indexOf()	
remove	um	elemento	da	lista	usando	o	método		splice()	
Agora,	então,	um	trecho	do	código	do	Template:
Excluindo	uma	disciplina
55
https://github.com/jacksongomesbr/angular-escola/tree/livro-excluindo-disciplina
<h1>Disciplinas</h1>
<hr>
<ul>
				<li	*ngFor="let	disciplina	of	disciplinas">
								{{disciplina.nome}}
								<button	(click)="excluir(disciplina)">
												Excluir
								</button>
				</li>
</ul>
<h2>Cadastrar</h2>
<p>Use	este	formulário	para	cadastrar	uma	disciplina.</p>
<form	#cadastro="ngForm"	(submit)="salvar()">
...
</form>
A	parte	importante	do	template	é	o	elemento		button		ao	lado	do	nome	da	disciplina.	Há	um
tratador	do	evento		(click)		que	chama	o	método		excluir()		passando	como	parâmetro	a
	disciplina		atual	da	repetição	do		*ngFor	.
O	resultado	da	execução	do	software	no	browser	é	ilustrado	pela	figura	a	seguir.
Excluindo	uma	disciplina
56
Figura	2.9.1	-	Execução	do	software	no	browser	ilustrando	a	confirmação	do	usuário	para
excluir	uma	disciplina
Esse	capitulo	é	bem	curto	e	não	há	muito	o	que	resumir,	mas	é	bom	notar	que	os	conceitos
vistos	nos	capítulos	anteriores	continuam	funcionando	aqui,	mesmo	que	em	aplicações
diferentes.
Excluindo	uma	disciplina
57
Editando	dados	de	uma	disciplina
[info]	Objetivos	do	capítulo:
demonstrar	a	implementação	do	requisito	"Editar	dados	de	uma	disciplina"
reforçar	os	conceitos	anteriores
demonstrar	a	implementação	mais	completa	de	um	CRUD
Branch:	livro-crud-disciplina
Como	o	capítulo	anterior,	esse	capítulo	não	é	muito	extenso	em	termos	de	conceitos	novos.
Entretanto,	ele	reúne	os	capítulos	anteriores	para	implementar	um	CRUD,	que	significa:
Create	(cadastrar)
Retrieve	(recuperar,	listar,	consultar)
Update	(atualizar,	editar)
Delete	(excluir)
A	figura	a	seguir	ilustra	a	interface	do	software	como	construída	ao	final	do	capítulo.
Editando	dados	de	uma	disciplina
58
https://github.com/jacksongomesbr/angular-escola/tree/livro-crud-disciplina
Figura	2.10.1	-	Software	com	o	CRUD	de	Disciplinas
A	interface	continua	com	duas	partes:	uma	apresentando	uma	lista	e	outra	apresentando
um	formulário.	Na	lista,	para	cada	item,	há	dois	botões:	"Excluir"	e	"Editar".	Ao	clicar	no
botão	"Excluir"	o	software	solicita	uma	confirmação	do	usuário.	Ao	clicar	no	botão	"Editar"
os	dados	da	disciplina	em	questão	são	apresentados	no	formulário	(nome	e	descrição).
Nesse	momento	o	formulário	entra	no	modo	de	edição	e:
se	o	usuário	clicar	em	"Salvar"	os	dados	da	disciplina	serão	atualizados
se	o	usuário	clicar	em	"Cancelar"	qualquer	alteração	não	será	armazenada
O	modo	padrão	do	formulário	é	o	cadastro.	Nesse	sentido	se	o	usuário	preencher	os
campos	(nome	e	descrição)	e:
clicar	em	"Salvar",	os	dados	serão	armazenados	em	uma	nova	disciplina,
apresentando-a	na	lista
clicar	em	"Cancelar",	os	dados	não	serão	armazenados
Vamos	ao	código-fonte.	Primeiro,	um	trecho	do	Controller:
Editando	dados	de	uma	disciplina
59
...
export	class	AppComponent	{
		editando	=	null;
		nome	=	null;
		descricao	=	null;
		disciplinas	=	[
				new	Disciplina('Língua	Portuguesa',	'O	objetivo	norteador	da	BNCC...'),
				...
		];
		salvar()	{
				if	(this.editando)	{
						this.editando.nome	=	this.nome;
						this.editando.descricao	=	this.descricao;
				}	else	{
						const	d	=	new	Disciplina(this.nome,	this.descricao);
						this.disciplinas.push(d);
				}
				this.nome	=	null;
				this.descricao	=	null;
				this.editando	=	null;
		}
		excluir(disciplina)	{
				if	(this.editando	==	disciplina)	{
						alert('Você	não	pode	excluir	uma	disciplina	que	está	editando');
				}	else	{
						if	(confirm('Tem	certeza	que	deseja	excluir	a	disciplina	"'
										+	disciplina.nome	+	'"?'))	{
								const	i	=	this.disciplinas.indexOf(disciplina);
								this.disciplinas.splice(i,	1);
						}
				}
		}
		editar(disciplina)	{
				this.nome	=	disciplina.nome;
				this.descricao	=	disciplina.descricao;
				this.editando	=	disciplina;
		}
		cancelar()	{
				this.nome	=	null;
				this.descricao	=	null;
				this.editando	=	null;
		}
}
As	novidades	são:
adição	do	atributo		editando	:	é	inicializado	com	null	e	manterá	uma	referência	para	a
Editando	dados	de	uma	disciplina
60
disciplina	que	está	sendo	editada	(quando	houver	alguma)
atualização	no	método	salvar()	:	para	tratar	a	situação	do	formulário	(cadastrando	ou
editando	disciplina)
atualização	no	método		excluir()	:	para	tratar	a	situação	em	que	o	usuário	quer	excluir
uma	disciplina	que	está	sendo	editada
adição	do	método		editar()	
O	método		salvar()		tem	um	novo	comportamento:	se	o	usuário	estiver	editando	uma
disciplina	(verifica	o	valor	do	atributo		editando	),	então	usa	os	dados	do	formulário	e
atualiza	os	dados	da	disciplina	que	está	sendo	editada.	Caso	contrário,	continua	com	o
comportamento	anterior:	usa	os	dados	do	formulário	para	criar	uma	instância	de
	Disciplina		e	adiciona	no	vetor		disciplinas	.
O	método		excluir()		tem	um	novo	comportamento:	se	o	usuário	estiver	editando	uma
disciplina	(verifica	o	valor	do	atributo	editando),	então	informa	o	usuário	que	não	é	possível
excluir	a	disciplina	que	está	sendo	editada.	Caso	contrário,	continua	com	o	comportamento
normal:	solicita	uma	confirmação	do	usuário	e	exclui	a	disciplina.
O	método		editar()		recebe	como	parâmetro	um	objeto	que	representa	a	disciplina	a	ser
editada,	atualiza	os	campos	do	formulário	com	os	atributos	de		disciplina		e	faz	com	que	o
atributo		editando		receba		disciplina		para	indicar	que	o	formulário	está	no	modo	de
edição	(há	uma	disciplina	sendo	editada).
O	método		cancelar()		tem	a	função	de	reiniciar	o	formulário	para	os	valores-padrão,
atributo	o	valor		null		para	os	atributos		nome	,		descricao		e		editando	.
Para	concluir,	o	Template:
Editando	dados	de	uma	disciplina
61
<h1>Disciplinas</h1>
<hr>
<ul>
				<li	*ngFor="let	disciplina	of	disciplinas">
								{{disciplina.nome}}
								<button	(click)="excluir(disciplina)">
												Excluir
								</button>
								<button	(click)="editar(disciplina)">

Continue navegando