You are on page 1of 16

EntendaClosuresnoJavaScriptcomFacilidade

(http://javascriptbrasil.com/2013/10/12/entendaclosuresno
javascriptcomfacilidade/)

AprendaAngularJScomestes5ExemplosPrticos
(http://javascriptbrasil.com/2013/10/23/aprendaangularjscom
estes5exemplospraticos/)

GuiaDefinitivoparaAprender
AngularJSemUmDia
(http://javascriptbrasil.com/2013/10/
18/guiadefinitivoparaaprender
angularjsemumdia/)
Postedon18/10/2013(http://javascriptbrasil.com/2013/10/18/guiadefinitivoparaaprender
angularjsemumdia/)byEricOliveira(http://javascriptbrasil.com/author/ericoliveira/)

Artigotraduzido.Postadooriginalmenteemtoddmotto.com
(http://toddmotto.com/ultimateguidetolearningangularjsinoneday/)em
02/10/2013

(http://javascriptbrasil.com/wpcontent/uploads/2013/10/rsz_angularjs.jpg)

OqueAngularJS?
AngularumframeworkclientsideMVC/MVVMfeitoemJavaScript,essencialpara
modernassinglepagewebapplicationsSPA(aplicaesdeumapgina)eatmesmo
sites.umgrandesaltoparaofuturodoHTMLeparaoqueoHTML5traz,eumsopro

dearfrescoquandoseestlidandocomawebmoderna.Estepostumcursocompleto
doincioaofim,feitoapartirdeminhasexperincias,conselhosemelhoresprticas,
aprendidasusandoo.

Terminologia
Angulartemumacurvadeaprendizagemdecurtoprazo,masdevemosnosfamiliarizar
comaterminologiaepensamentoMVC.MVCsignificaModelViewController(Modelo
VisoControlador).

MVC
VocprovavelmenteouviusobreMVC,usadoemvriaslinguagensdeprogramaocom
osentidodeestruturao/arquiteturaodeaplicaes/softwares.Aquiestosignificado
decadaumadaspartes:
Model(Modelo):aestruturadedadoatrsdeumaparteespecficadaaplicao,
usualmenteportadaemJSON.LeiasobreJSONantesdeiniciarcomAngular,pois
essencialparaacomunicaodoseuservidoreview.Porexemplo,umgrupodeIDsde
usuriopodeseguiroseguintemodelo:

1
2
3
4
5
6
7
8
9

{
"users": [{
"name": "Joe Bloggs",
"id": "82047392"
}, {
"name": "John Doe",
"id": "65198013"
}]
}

VocvaientopegarestainformaooudoservidorviaXHR(XMLHttpRequest),com
jQueryvocconheceistocomoomtodo$.ajaxecomosenvlucros(wraps)doAngular
como$http,ouistovaiserescritonoseucdigoenquantoapginaparseada(deum
bancodedados).Vocpodeentoenviaratualizaesparaseumodeloepeglasde
volta.
View(Viso):Oviewsimples,eleseuHTMLe/ousadarenderizada.Usandoum
frameworkMVC,vocirpegarosdadosdoModelqueatualizaseuViewemostraras
informaesrelevantesemseuHTML.
Controller(Controlador):Elefazoquediznaembalagem,controlacoisas.Masque
coisas?Dados.Controllerssoseuacessodiretodoservidorparaoview,seu
intermedirio,atualizandoosdadosemtemporealviacomunicadoresentreoservidoreo

cliente.

CriaodeUmProjetoAngularJS(mnimoessencial)
Primeiro,nsprecisamosdefatoconfiguraroessencialparaumprojetoAngular.H
certascoisasparaseobservarantesdecomearmos,quegeralmenteconsisteemuma
declaraongappparadefinirsuaaplicao,umControllerparaconversarcomsua
View,ealgumaligaoDOMeinclusodoAngular.Aquitemosomnimoessencial:
UmpoucodeHTMLcomdeclaraesng*:

1
2
3
4
5

<div ng-app="myApp">
<div ng-controller="MainCtrl">
<!-- controlador lgico -->
</div>
</div>

UmmduloAngulareumControlador:

1
2
3
4
5

var myApp = angular.module('myApp', []);

myApp.controller('MainCtrl', ['$scope', function ($scope) {


// Controller mgico
}]);

Antesdeaprofundarmos,nsprecisamoscriarummduloAngularoqualtodanossa
lgicaseracoplada.Hvriasformasdedeclararmdulos,evocpodeencadeartoda
sualgicaassim(Eunogostodestemtodo):

1
2
3
4

angular.module('myApp', [])
.controller('MainCtrl', ['$scope', function ($scope) {...}])
.controller('NavCtrl', ['$scope', function ($scope) {...}])
.controller('UserCtrl', ['$scope', function ($scope) {...}]);

CriarummduloglobalprovouseramelhormaneiraemprojetosAngularqueeu
trabalhei.Afaltadepontoevrgulaeofechamentoacidentaldoencadeamento
notoriamentecontraproducente(improdutivo)efrequentementenoslevaaerrosde
compilaodesnecessrios.Faaassim:

1
2
3
4

var myApp = angular.module('myApp', []);


myApp.controller('MainCtrl', ['$scope', function ($scope) {...}]);
myApp.controller('NavCtrl', ['$scope', function ($scope) {...}]);
myApp.controller('UserCtrl', ['$scope', function ($scope) {...}]);

Cadanovoarquivoqueeucriarsimplementepegoonamespaceeautomaticamente
estamosconectadoscomaaplicao.Sim,euestoucriandonovosarquivosparacada
Controlador,Diretiva,Factoryetudomais(vocvaimeagradecerporisto).Concateneos

eenvieoscriptniconoDOMdinamicamenteusandoalgocomoGrunt.

Controladores
AgoraquevoccompreendeuoconceitodoMVCeaconfiguraobsica,vamos
verificaraimplementaodoAngularecomovocpodetrabalharcomControladores.
Pegandooexemploacima,nspodemosfazerumbabystep(passodebeb)emcomo
inseriralgunsdadosnoDOMapartirdeumcontrolador.OAngularusaestilodetemplate
comsintaxe{{handlebars}}paraconversarcomoseuHTML.OHTML
(preferencialmente)nodevecontertextosfsicosoupesadoscdigos,paraquesefaa
omelhordoAngular.AquitemosumexemplodeinserodeumasimplesStringno
DOM.

1
2
3
4
5

<div ng-app="myApp">
<div ng-controller="MainCtrl">
{{ text }}
</div>
</div>

1
2
3
4
5

var myApp = angular.module('myApp', []);

myApp.controller('MainCtrl', ['$scope', function ($scope) {


$scope.text = 'Ol, f de Angular =)';
}]);

Eoresultadoaovivo:http://jsfiddle.net/toddmotto/mN7QB/light/
(http://jsfiddle.net/toddmotto/mN7QB/light/)
Oregrachaveaquioconceitode$scope,quevocirligarcomtodasassuasfunes
dentrodoscontroladoresespecficos.O$scopeserefereaoatualelemento/readoDOM
(no,noomesmoquethis),eencapsularumescopointeligenteecapazdemanteros
dadosealgicacompletamentesituadosdentrodoselementos.IssotrazaoJavaScript
escopospblicos/privadosparaoDOM,oquefantstico.
Oconceitode$scopepodeserassustadornocomeo,masasuaconexocomoDOM
comoservidor(edadosestticossevoctambmostiver)!Ademonstraolhedeua
ideiabsicadecomovocpodeinserirdadosnoDOM.
Vamosconferirumaestruturamaisrepresentativasemqueteremoshipotticamente
dadosrecuperadosdoservidorparamostrardetalhesdologindeusurios.Poragoravou
usardadosestticos,maisafrenteireilhemostrarcomobuscardadosJSONdinmicos.
PrimeirovamosconfiguraroJavaScript:

1
2
3
4
5
6
7
8
9
10
11
12
13

var myApp = angular.module('myApp', []);

myApp.controller('UserCtrl', ['$scope', function ($scope) {

//Criando o namespace user details


//Que nos ajudar no visual do DOM
$scope.user = {};
$scope.user.details = {
"username": "Todd Motto",
"id": "89101112"
};

}]);

AgoraportandoissoparaoDOMparamostrarmosestesdados:

1
2
3
4
5
6

<div ng-app="myApp">
<div ng-controller="UserCtrl">
<p class="username">Bem-vindo, {{ user.details.username }}</p>
<p class="id">ID do usurio: {{ user.details.id }} </p>
</div>
</div>

Resultado:http://jsfiddle.net/eo_op/xJdWk/(http://jsfiddle.net/eo_op/xJdWk/)
importantelembrarqueosControladoressoparadadossomente,efunes(funes
deeventotambm)queconversemcomoservidoreinsiram/busquemdadosJSON.
ManipulaoDOMnodeveserfeitaaqui,entodeixeseukitjQuerydefora.Diretivas
soparamanipulaodoDOM,eseroprximotpico.
Dicaprofissional:portodaadocumentaodoAngular(atomomentoqueescrevo
isso),seusexemplosmostramessaformadesecriarControladores:

1
2
3
4
5

var myApp = angular.module('myApp', []);

function MainCtrl ($scope) {


//...
}

NOFAAISSO!!!Istoexpemtodasassuasfunesnoescopoglobalenoas
deixamligadasdeumaboamaneiracomsuaaplicao.Tambmfazcomquevocno
consigaminificarseucdigooufaatestesfacilmente.Nopoluaonamespaceglobale
deixeoscontroladoresDENTROdesuaaplicao.

Diretivas
Umadiretiva(confirameupostemDiretivasapartirdescripts/pluginsexistentes
(http://toddmotto.com/creatinganangularjsdirectivefromoneofyourexistingplugins
scripts/))emsuaformamaissimplesumpequenopedaodeHTMLmodelado,
preferencialementeusadomltiplasvezesduranteaaplicaoondenecessria.uma

maneirasimplesdeinetaroDOMnasuaaplicaosemnenhumesforo,realizando
interaesDOMpersonalizadas.Diretivasnososimplesnoentando,humaincrvel
curvadeaprendizadoparaconquistlastotalmente,pormaprximaetapairdeixlo
prontoparacomear.
Entoparaoquasdiretivassousadas?Vrioscoisas,incluircomponentesDOM,por
exemploabasouelementosdenavegaorealmentedependedoquesuaaplicao
fazusodainterfacedousurio(UIUserInterface).Sevocjbrincoucomngshowou
nghide,elassodiretivas(emboranoinjetemnoDOM).
Paraesteexerccio,ireideixarissorealmentesimplesecriarumtipodeboto
customizado(chamadocustomButton)queinjetaalgumamarcaoqueeuodeiodoter
queficarescrevendo.HvriasmaneirasdedefinirDiretivasnoDOM,elaspodemse
parecercomisso:

1
2
3
4
5
6
7
8
9
10
11

<!-- 1: como uma declarao de atributo -->


<a custom-button>Click me</a>

<!-- 2: como um elemento personalizado -->


<custom-button>Click me</custom-button>

<!-- 3: como uma classe (usado para compatibilizao nos IE antigos) -->
<a class="custom-button">Click me</a>

<!-- 4: como um comentrio (no boa para este exemplo, entretanto) -->
<!-- directive: custom-button -->

Euprefirouslascomoumatributo,elementoscustomizadosestovindonofuturodo
HTML5juntocomWebComponents,masosrelatriosdoAngularcomelesmostram
vrioserrosemnavegadoresantigos.
AgoraquevocsabecomodeclarareondeasDiretivassousadas/injetadas,vamos
criarobotopersonalizado.Novamente,euvouligaronamespaceglobaldaminha
aplicaocomomyApp,sendoestaadiretivanasuaformamaissimples:

1
2
3
4
5
6
7

myApp.directive('customButton', function () {
return {
link: function (scope, element, attrs) {
// Manipulao e Eventos no DOM aqui!
}
};
});

Eudefiniminhadiretivausandoomtodo.directive(),eachameicustomButton.Quando
voccapitalizaumaletranonomedadiretiva,eladeveserseparadacomhfennoDOM
(comomostradoacima).

Umadiretivasimplesmenteretornaasimesmacomoumobjeto(Object)eassumeum
nmerodeparmetros.Omaisimportanteparamim,desedominarprimeiro,restrict,
replace,transclude,templateetemplateUrl,eparansapropriedadelink.Vamos
adicionarasoutraspropriedades:

1
2
3
4
5
6
7
8
9
10
11
12
13

myApp.directive('customButton', function () {
return {
restrict: 'A',
replace: true,
transclude: true,
template: '<a class="myawesomebutton">' +
'<i class="icon-ok-sign"></i>' +
'</a>',
link: function (scope, element, attrs) {
// Manipulao e Eventos DOM aqui!
}
};
});

Resultado:http://jsfiddle.net/toddmotto/VC4H2/light/
(http://jsfiddle.net/toddmotto/VC4H2/light/)
Inspecioneoelementoevejaasmarcaesadicionaisqueforaminjetadas.Sim,eusei,
nohiconeinclusoporqueeunoincluioFontAwesome,masvocviucomo
funciona.AgoravamosparaasexplicaesdaspropriedadesdasDiretivas:
restrict:issoremontaautilizao,comoiremosrestringirousodoselementos?Sevoc
estiverusandoumprojetoquenecessitedarsuporteaoIElegado,vocprovavelmente
precisardedeclaraesdeatributos/classes.RestringindocomAsignificaquevoc
restringiuissocomoatributo.Eparaelemento,CparaclasseeMparacomment.
ComopadrotemosEA.Sim,vocpoderestringirparamltiploscasosdeuso.
replace:IstosubstituiamarcaonoDOMquedefineadiretiva,comousadono
exemplo,vocirnotarcomooDOMinicialsubstituidocomotemplate(modelo)da
Diretiva.
transclude:Simplificando,usandotranscludevocpermitequecontedoexistenteno
DOMsejacopiadodentrodadiretiva.VocveraspalavrasClickmehavemoved
dentrodaDiretivaquandoelaforrenderizada.
template:Umtemplate(comoacima)permitequevocdeclareumamarcaoaser
injetada.umaboaideiausaristoparaminsculopedaosdeHTMLsomente.
TemplatesinjetadossotodoscompiladospeloAngular,istosignificaquevocpode
declararashandlebartemplatetags{{}}dentrodelestambmparaligao.

templateUrl:Similaraotemplate,masmantidoemseuprprioarquivooutagscript.
VocpodefazerissoparaespecificarummodelodeURL,quevocvaiquererusarpara
manipularpedaosdeHTMLquerequeremmanterseemseuprprioarquivo,somente
especificandoocaminhoenomedoarquivo,preferencialmentemantidosdentrodos
prpriosdiretriostemplates:

1
2
3
4
5
6

myApp.directive('customButton', function () {
return {
templateUrl: 'templates/customButton.html'
// coisas da diretiva...
};
});

Edentrodoseuarquivo(nomedoarquivonosensitivoatodos):

1
2
3
4

<!-- dentro do customButton.html -->


<<a href="" class="myawesomebutton" ng-transclude>
<i class="icon-ok-sign"></i>
</a>

Oquerealmentebomemsefazerisso.queonavegadorirefetivamentecachearo
arquivoHTML,bravo!Aoutraalternativaquenoutilizaocachedeclararotemplate
dentrodatagscript:

1
2
3
4
5

<script type="text/ng-template" id="customButton.html">


<a href="" class="myawesomebutton" ng-transclude>
<i class="icon-ok-sign"></i>
</a>
</script>

VocirdizeraoAngularquehumngtemplateeirdaraeleumID.OAngularir
entobuscarpelongtemplateouoarquivo*.html,entosejaqualforsuapreferncia.Eu
prefirocriararquivos*.htmlporseremfceisdelidar,melhoraremodesempenhoe
manteroDOMmuitolimpo,poisvocpodeacabarcom1ou100diretivas,eirquerer
sercapazdenavegarentreelasfacilmente.

Servios(Services)
Serviosgeralmentesoumpontoconfuso.Apartirdeexperinciaepesquisa,elesnos
domaisumpadrodeprojetoestilizadodoquediferenascommaisfuncionalidade.
VocdeveusarosServicesparasingletons,eFactoriesparafunesmaiscomplexas
comoObjetosLiteraisecasosdeusomaiscomplicados.
AquitemosumexemplodeServicequemultiplicadoisnmeros:

1
2
3
4
5

myApp.service('Math', function () {
this.multiply = function (x,y) {
return x * y;
};
});

VocpodeentousarumControladorassim:

1
2
3
4
5
6
7

myApp.controller('MainCtrl', ['$scope', function ($scope) {


var a = 12;
var b = 24;

//sada 288
var result = Math.multiply(a, b);
}]);

Sim,multiplicaomuitofcilenoprecisadeumService,masvocentendeua
essncia.
QuandovoccriarumService(ouFactory),vocvaiprecisardeusarainjeode
dependnciaparadizeraoAngularqueeleprecisaligarseunovoserviocasocontrrio
vocterumerrodecomplicaoeseuControladorirquebrar.Vocdeveternotadona
umapartefunction($scope)dentrodadeclaraodoControladoragora,eissoa
simplesinjeodedependncia.Voctambmirnotar[$scope]antesdafunction
($scope),ireivoltarnissomaistarde.Aquiestcomousarinjeodedependnciapara
dizeraoAngularquevocprecisadoService:

1
2
3
4
5
6
7

myApp.controller('MainCtrl', ['$scope', 'Math', function ($scope, Math) {


var a = 12;
var b = 24;

// sada 288
var result = Math.multiply(a, b);
}]);

Factories
VindodosServicesosFactoriessetornammaissimples,nspodemoscriarObjetos
LiteraisdentrodeumFactoryousimplesmentefornecermtodosmaisprofundos:

1
2
3
4
5
6
7
8
9
10

myApp.factory('Server', function () {
return {
get: function (url) {
return $http.get(url);
},
post: function (url) {
return $http.post(url);
}
};
});

Aquieuestoucriandoumwrapper(empacotador)paraXMLHttpRequest(XHR)do
Angular.DepoisdainjeodedependnciadentrodoControlador,ousosimples:

1
2
3
4
5
6

myApp.controller('MainCtrl', ['$scope', 'Server', function ($scope, Server) {


var jsonGet = 'http://myserver/getURL';
var jsonPost = 'http://myserver/postURL';
Server.get(jsonGet);
Server.post(jsonPost);
}]);

Sevocquiserconsultaroservidorparamudanas,vocpodeentoconfigurar
Server.poll(jsonPoll),outalvezsevocestiverusandoumSocketvocpodeconfigurar
Server.socket(jsonSocket).Issoabrirportasparavocmodularizarcdigoassimcomo
criarferramentasparavocusaremanterocdigodentrodosControladores
minimamente.

Filters(Filtros)
Filterssousadosemconjuntocomarraysdedadosetambmsadasdeloops.Sevoc
estiveremumloopdedadosequiserfiltrarcoisasespecficas,vocestnolugarcerto,
vocpodetambmusarosFiltersparafiltraroqueumusurioescreveudentrodeum
inputporexemplo.TemosalgumasformasdeuserosFilters,dentrodosControladores
oucomoummtododefinido.Aquiestautilizaopormtodo,quevocpodeusar
globalmente:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

myApp.filter('reverse', function () {
return function (input, uppercase) {
var out = '';
for (var i = 0; i &lt; input.length; i += 1) {
out = input.charAt(i) + out;
}
if (uppercase) {
out = out.toUpperCase();
}
return out;
}
});

//Controlador incluso para fornecer dados


myApp.controller('MainCtrl', ['$scope', function ($scope) {
$scope.greeting = 'Todd Motto';
}]);

UsonoDOM:

1
2
3
4
5
6

<div ng-app="myApp">
<div ng-controller="MainCtrl">
<p>No filter: {{ greeting }}</p>
<p>Reverse: {{ greeting | reverse }}</p>
</div>
</div>

Sada:http://jsfiddle.net/toddmotto/pmh4s/light/(http://jsfiddle.net/toddmotto/pmh4s/light/)
Utilizandodentrodeumngrepeat:

1 <ul>
2 <li ng-repeat="number in myNumbers | filter:oddNumbers">{{ number }}</li>
3 </ul>

EaquitemosumexemplorpidorealdeumFilterdentrodeumControlador:

1
2
3
4
5
6
7
8
9
10
11
12

myApp.controller('MainCtrl', ['$scope', function ($scope) {

$scope.numbers = [10, 25, 35, 45, 60, 80, 100];

$scope.lowerBound = 42;

//Fazendo os Filters
$scope.greaterThanNum = function (item) {
return item > $scope.lowerBound;
};

}]);

Eseuusodentrodeumngrepeat:

1 <li ng-repeat="number in numbers | filter:greaterThanNum">


2 {{ number }}
3 </li>

Sada:http://jsfiddle.net/toddmotto/cZbCf/light/(http://jsfiddle.net/toddmotto/cZbCf/light/)
EssaaparteprincipalatrsdoAngularJSesuaAPI,masestamosapenasnaparte
rasasobreoassunto,pormissojmaisquesuficienteparavoccomearaconstruir
suaaplicaocomAngular.

Twowaydatabinding(Duasviasdeligaodedados)
Quandoeuouvisobretwowaydatabinding(duasviasparaligaodedados),euno
entendirealmenteoqueissoseria.Twowaydatabindingmelhordescritacomoum
ciclocompletodesincronismodedados:atualizaoModeleatualizaoView,atualizao
VieweatualizaoModel.Issosignificaqueodadosemantmsincronizadosemprecisar
deexageros.Seeuligarumngmodelcomuminputecomearaescrever,issocriar(ou
atualizarsejexistente)ummodeloaomesmotempo.
AquieucrieiuminputeoligueiaomodelochamadomyModel,assimeupossoento
usarasintaxedechavespararefletirestemodeloeeleseratualizadonoViewno
mesmomomento:

1
2
3
4
5
6

<div ng-app="myApp">
<div ng-controller="MainCtrl">
<input type="text" ng-model="myModel" placeholder="Start typing...">
<p>Meu modelo de dado: {{ myModel }}</p>
</div>
</div>

1
2
3
4
5

myApp.controller('MainCtrl', ['$scope', function ($scope) {


//Captura o modelo de dado
//e/ou inicializa-o com a string existente
$scope.myModel = '';
}]);

Resultado:http://jsfiddle.net/toddmotto/qrr3q/light/
(http://jsfiddle.net/toddmotto/qrr3q/light/)

XHR/Ajax/$httpchamadaseligaoJSON
Vocpegouaideiaquandocomeamosainserirdadosparao$scope,eumanoo
superficialdecomoosModelsetwowaydatabindingfuncionam,entoagorahorade
simularalgumachamadaXHRrealcomumservidor.Parawebsites,istono
necessriosevoctiverumarequisioAjaxespecfica,issoprincipalmentefocadoem
levardadosparaumaaplicaoweb.
Quandovocestdesenvolvendolocalmente,vocpossivelmenteestusandoalgo
comoJava,ASP,.NET,PHPouqualqueroutracoisaquerodeemumservidorlocal.Se
vocestiversecomunicandocomumbancodedadoslocalourealmenteusandoo
servidorcomoumaAPIparacomunicarsecomoutrorecurso,usaremosamesma
configurao.
Digitedollarhttp.Seumelhoramigoapartirdeagora.Omtodo$httpumbelowrapper
doAngularparaacessardadosdoservidor,edetofcilvocpodefazerissodeolhos
fechados.AquitemosumsimplesexemplodeumarequisioGET,que(voc
adivinhou)pegadadosvindosdoservidor.SuasintaxemuitoparecidacomjQuerypor
issosuatransioserbemsuave:

1
2
3
4
5
6

myApp.controller('MainCtrl', ['$scope', function ($scope) {


$http({
method: 'GET',
url: '//localhost:9000/someurl'
});
}]);

OAngularentoretornaalgochamadopromise,queumamaneiramuitomaiseficiente
elegveldemanusearoscallbacks.Promisessoencadeadosnasfunesemqueso
iniciadosapartirdanotaoporpontomyPromise().Comoexperado,nsrecebemos

respostasdeerroousucesso.

1
2
3
4
5
6
7
8
9
10
11
12

myApp.controller('MainCtrl', ['$scope', function ($scope) {


$http ({
method: 'GET',
url: '//localhost:9000/someUrl'
})
.sucess (function (data, status, headers, config) {
//recuperao de dados bem sucedida
})
.error (function (data, status, headers, config) {
//alguma erro ocorreu :(
});
}]);

Muitobomelegvel.AquiondensfundimosaViewcomoservidorpelaligaoaum
ModelouatualizamososdadosdoModelnoDOM.Vamosassumirumaconfiguraoe
enviarumusernameaoDOM,viaumachamadaAjax.
Idealmente,nsdevemosconfigurarprimeiroummodeloparanossoJSON,queser
transportadoquandonsligarmosnossosdados.Vamosdeixlosimples,issoser
comoumcaradobackendirconfigurarcomoumaAPIiralimentarsuaaplicao,
sendoporvocesperadooseguinte:

1
2
3
4
5
6

{
"user": {
"name": "Todd Motto",
"id": "80138731"
}
}

IssosignificaqueiremosreceberumObjetoretornadodoservidor(comumapelidoque
chamaremosdado[vocverqueodadopassadodentrodosnossosmanuseadores
promise]),etemosqueentraremdado.usuarioPropriedade.Dentrode
dado.usuarioPropriedade,nstemosnameeid.Acesslosfcil,nsprecisamosde
procurarpordata.user.namequensretornarToddMotto.Agoravamosbuscarisso!
OJavaScript(chequeasnotaesparasaberoqueestacontecendoaqui):

1
2
3
4
5
6
7
8
9
10
11
12
13

myApp.controller ('UserCtrl', ['$scope', function ($scope) {

//crie um Objeto user


$scope.user = {};

//Inicialize um modelo como uma string vazia


$scope.user.name = '';

//Ns precisamos fazer uma chamada e um get


//o nome do usurio
$http ({
method: 'GET',
url: '//localhost:9000/someUrlForGettingUsername'

14
15
16
17
18
19
20
21
22
23

})
.sucess (function (data, status, headers, config) {
//Veja aqui, ns estamos agora atribuindo este username
//ao nosso Model existente!
$scope.user.username = data.user.name;
})
.error (function (data, status, headers, config) {
// algum erro aconteceu :(
});
}]);

EagoranoDOM,nspodemosfazeroseguinte:

1 <div ng-controller="UserCtrl">
2 <p>{{ user.username }}</p>
3 </div>

Issoirimprimirousername.Agoransvamosiralmparaentenderdeclarativedata
binding(ligaodedadosdeclarativos)queondeascoisasficamrealmente
empolgantes.

DeclarativeDataBinding(LigaodeDadosDeclarativos)
AfilosofiadoAngularcriarHTMLdinmicoquesejaricoemfuncionalidadeefaa
muitostrabalhosperfeitamentequevocnuncaexperarianoladodoclientedaweb.Isto
exatamenteoqueelesentregam.Vamosimaginarquensfizemosumarequisio
AjaxparapegarumalistadeemailsesualinhaAssunto,dadosforamenviadosens
queremosrenderizlosnoDOM.AiondeosqueixoscaemdianteopoderdoAngular.
PrimeironsvamosprecisardeconfigurarumControladorparaEmails:

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

myApp.controller ('EmailCtrl', ['$scope', function ($scope) {

// crie um Objeto emails


$scope.emails = {};

// simulando dados que ns iremos receber de volta do servidor


// este um ARRAY de OBJETOS
$scope.emails.messages = [{
"from": "Steve Jobs",
"subject": "I think I'm holding my phone wrong :/,
"sent": "2013-10-01T08:05:59Z"
},{
"from": "Ellie Goulding",
"subject": "I've got Starry Eyes, lulz",
"sent": "2013-09-21T19:45:00Z"
},{
"from": "Michael Stipe",
"subject": "Everybody hurts, sometimes.",
"sent": "2013-09-12T11:38:30Z"
},{
"from": "Jeremy Clarkson",
"subject": "Think I've found the best car... In the world",
"sent": "2013-09-03T13:15:11Z"
}];
}]);

AgoraprecisamosconectarissodentrodonossoHTML.Aquiondensvamosusaras
ligaesdeclarativas(declarativebinding)paradeclararoqueaaplicaoirfazerpara
criarnossoprimeiropedaodeHTMLdinmico.VamosusaradiretivadoAngularng
repeatembutida,quevaiiterarsobreosdadoserenderizarumasadasem
absolutamentenenhumcallbackoumudandeestado,tudodegraa:

1
2
3
4
5
6
7

<ul>
<li ng-repeat="message in emails.messages">
<p>From: {{ message.from }}</p>
<p>Subject: {{ message.subject }}</p>
<p>{{ message.sent | date:'MMM d, y h:mm:ss a' }}</p>
</li>
</ul>

Resultado:http://jsfiddle.net/toddmotto/TAVQc/light/
(http://jsfiddle.net/toddmotto/TAVQc/light/)
Eutambmcoloqueisorrateiramenteumfiltrodedados(datafilter)paravocpoderver
comorenderizardatasnopadroUTC.
Aprofundenasuitedediretivasng*doAngularparaliberartodoopoderdasligaes
declarativas,poislhemostracomojuntarospontosdoservidordoModelaoViewe
renderizardados.

FunesdeEscopo
Comocontinuaodasligaesdeclarativas,funesdeescoposooprximonvelna
criaodeumaaplicaocomalgumafuncionalidade.Aquitemosumafunobsicade
deletarumdenossosdadosnoemail:

1
2
3
4
5

myApp.controller ('MainCtrl', ['$scope', function ($scope) {


$scope.deleteEmail = function (index) {
$scope.emails.messages.splice (index, 1)
};
}]);

Dicaprofissional:importantepensarsobredeletardadosdoModel.Vocnoest
deletandoelementosououtracoisarealrelacionadaaoDOM,Angularumframework
MVCevaimanuseartudoistoparavoccomsuatwowaybinding(ligaodeduas
vias)eomundolivredecallback,vocsomenteprecisaconfigurarseucdigodeforma
inteligenteparadeixloresponderaosseusdados.
LigarfunesaoescopotambmocorreatravsdasDiretivasng*,agorausaremosa
Diretivangclick:

1 <a>Delete Email</a>

Estaumaformadiferenteparaosmanipuladoresdeclickinline,porvriasrazes.Esse
assuntoserabordadoembreve.Vocvaiverqueeutambmestoupassandoo$index,
eoAngularreconheceoitemquevocquerdeletar(quantocdigoequantalgica
salvaspravoc!).
Resultado(deletealgunsemails!):http://jsfiddle.net/toddmotto/BgZmt/light/
(http://jsfiddle.net/toddmotto/BgZmt/light/)

MtodosDOMDeclarativos
AgoransvamosentrarnosmtodosDOM,elessoDiretivasesimulamfuncionalidades
noDOMquevoctemnormalmentequeescrevermaiscdigoselgicasparatal.Um
grandeexemplodistopodeserumsimplesnavegadorquealterna(toggle).Usandong
showe