Professional Documents
Culture Documents
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
http://pt.discovermeteor.com/pdf
1/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
DISCOVERMETEOR
BuildingRealTimeJavaScriptWebApps
TomColeman&SachaGreif
Commons Attribution
2.0
Generic license
http://pt.discovermeteor.com/pdf
2/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Introduo
Voc
refreshes ou callbacks
Entretanto
a mudana
Quando n
s modificamos
Apenas acontece
quanto voc
espere
Mas Meteor
Ao contrrio do desktop
Por exemplo
no importa o
a atualize
separados acessos
Oquemeteor?
Meteor
tempo real
o que fica entre o banco de dados do seu app e a interface do usurio e garante
J que
. ,
O melhor
http://pt.discovermeteor.com/pdf
m consegue compartilhar c
3/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
aplicativos web
PorqueMeteor?
framework
resume a uma
nica coisa
Meteor
E se voc
nova linguagem
.
,
ser
voc
fcil de aprender
antes
s de um outro web
por
Porqueestelivro?
Ao longos dos
ltimos
meses
),
pense
um aplicativo
em muitos casos at
es
inventar nossas pr
es
prias solu
.
es
--
s gostar amos
O aplicativo que n
Telescope
s estamos construindo
Enquanto o construimos
de usurios
cole
es Meteor
http://pt.discovermeteor.com/pdf
roteamento
e mais
.
4/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
E ap
s voc
digo do Telescope
se voc
es
SobreosAutores
Caso voc
Tom Coleman
ncia do usurio
Meteor
rio de pacotes
s e porque voc
).
deveria confiar em n
aqui
.
,
Ele tamb
e est tamb
s dois
qualidade e experi
reposit
ncia de n
Sacha Greif tem trabalhado com startups tais como Hipmunk e RubyMotion na rea de
),
Telescope
e tamb
Ele tamb
o qual
baseado em
fundador do Folyo
CaptuloseBarrasLaterais
programadores avanados
regulares
numeradores de
ento n
1 14
a
e barras laterais
(.5
).
cap tulos
meros
s da construo do aplicativo
e tentaro te deixar o
mais operacional o mais cedo poss vel explicando os mais importantes passos sem lhe
e o
ajudaro a ter uma compreenso melhor do que realmente est acontecendo por trs das
cortinas
Ento se voc
leitura
um iniciante
http://pt.discovermeteor.com/pdf
5/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
CommitseLiveInstances
No h nada pior do que seguir um livro de programao e de repente perceber que o seu
digo est fora de sincronia com os exemplos e que nada mais funciona como deveria
,
n
s estabelecemos um reposit
Adicionalmente
commit em particular
ento voc
e n
s tamb
digo
pia local
Commit112
Ver no GitHub
Lanar Instncia
Mas perceba que apesar de provermos esses commits isso no significa que voc
ir de um
git checkout
ao pr
ximo
Voc
deva apenas
aproveitar o
AlgunsOutrosRecursos
Se voc
oficial do Meteor
s tamb
a documentao
http://pt.discovermeteor.com/pdf
e o
6/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
EuprecisodeGit?
Apesar de estar familiarizado com o Git version control no
s recomendamos muito
estritamente necessrio
Se voc
Se voc
Mac
um novato em Git
de comando
s tamb
EntrandoemContato
Se voc
hello
discovermeteor com
Adicionalmente
se voc
voc
Se voc
rio GitHub
no reposit
Finalmente
digo do Microscope
voc
do do livro
voc
rio do Microscope
comentrio para n
http://pt.discovermeteor.com/pdf
tamb
7/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
ComeandocomMeteor
Primeiras impress
es so importantes
relativamente indolor
voc
minutos
Para comear
,
n
$ curl https://install.meteor.com | sh
No
meteor
usar Meteor
InstalandoMeteor
Se voc
no pode
ou no quer
s recomendamos
checar Nitrous io
Nitrous io
e n
digo dos
a comear
Voc
Meteor
&
Meteorite
segmento
e incluindo
o segmento
Instalando
Meteorite
Meteor
Tom Coleman
Meteorite tamb
http://pt.discovermeteor.com/pdf
encontrar
um inv
um
lucro para
e juntando a ele
.
8/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
J que n
Microscope
InstalandoMeteorite
Voc
Instale os da
Segundo
formato padro de m
Como
),
dulo do Node
um executvel npm
s o instalaremos com
ErrosdePermisso?
sudo -H :
Voc
isso a
Nota
tutorial windows
mas voc
http://pt.discovermeteor.com/pdf
9/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
### mrt
meteor
vs
nosso aplicativo
Quando n
usaremos o executvel
entretanto
meteor .
CriandoumSimplesAplicativo
Agora que n
,
n
mrt :
voc
usar
Ap
s isto
voc
, microscope/ ,
rio
contendo o seguinte
microscope.css
microscope.html
microscope.js
smart.json
padr
demonstrando alguns
es simples
s j podemos rod lo
Para rod lo
v at
terminal e digite
$ cd microscope
$ meteor
http://pt.discovermeteor.com/pdf
10/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
http://0.0.0.0:3000/
e voc
http://localhost:3000/
ou o equivalente
MeteorsHelloWorld.
Commit21
Ver no GitHub
Parab
ns
Voc
rodando
Lanar Instncia
e pressionar
precisa fazer
Alis
ctrl+c .
AdicionandoumPacote
s agora usaremos Meteorite para adicionar um pacote inteligente que nos permitir incluir
http://pt.discovermeteor.com/pdf
11/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Commit22
Ver no GitHub
Lanar Instncia
UmanotasobrePacotes
O n
cleo do Meteor em si
e voc
Voc
meteor list
37
pacotes
que v
quando voc
voc
m embrulhados com
Eles
O Meteor
prio aplicativo
com
rio
los
em Atmosphere
Pacotes NPM
Meteorite
. .
so pacotes do Node js
de pacote pr
Atmosphere
Apesar deles
vios
AEstruturadeArquivosdeumAplicativoemMeteor
Antes de n
s comearmos a programar
http://pt.discovermeteor.com/pdf
12/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
apropriadamente
microscope
A seguir
rios ra z dentro de
rios so especiais
/server
/client
digo no diret
digo no diret
rio
rio
/lib
Qualquer arquivo
fonts
images
etc
vo no diret
/public .
rio
Arquivos no
Em relao a arquivos
sugerimos
vazios
main.js
rio
e delete
dentro de
abra o diret
no quiser
quiser mais
http://pt.discovermeteor.com/pdf
13/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
OMeteorMVC?
Se voc
est vindo para o Meteor de outros frameworks tais como Ruby on Rails
talvez voc
).
A resposta curta
no
Ao inv
s de Rails
Meteor no imp
acr
nimos
e nenhuma estrutura
s simplesmente deixaremos o
Nopblico?
OK
s mentimos
public/
rio
,
n
Alis
voc
pode tamb
guarda seu pr
voc
prio c
digo
rio
.meteor
.meteor/packages
rio
es do Meteor
pode ser
http://pt.discovermeteor.com/pdf
Aqui
geralmente um id
As
nicas excess
onde o Meteor
ia muito ruim
Alis
es a isto so os arquivos
vers
escondido
Quando voc
14/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
UnderscoresvsCamelCase
A
vs camelCase
que voc
( myVariable )
( my_variable )
escolha desde
permanea nele
Neste livro
fazer as coisas
As
nicas exce
underscores
at
JavaScript e no java
( my_file.js ),
os quais usaremos
!).
script
e classes em CSS
enquanto a pr
( .my-class ).
,
.
( font-family , text-align , )
etc
CuidandodasCSS
Este livro no
sobre CSS
jamais precise se
.
,
client/stylesheets/
agora
style.css
dentro dele
15/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
}
#spinner { height: 300px }
.post {
*zoom: 1;
-webkit-transition: all 300ms 0ms;
-webkit-transition-delay: ease-in;
-moz-transition: all 300ms 0ms ease-in;
-o-transition: all 300ms 0ms ease-in;
transition: all 300ms 0ms ease-in;
position: relative;
opacity: 1;
}
.post:before, .post:after {
content: "";
display: table;
}
.post:after { clear: both }
.post.invisible { opacity: 0 }
.post .upvote {
display: block;
margin: 7px 12px 0 0;
float: left;
}
.post .post-content { float: left }
.post .post-content h3 {
margin: 0;
line-height: 1.4;
font-size: 18px;
}
.post .post-content h3 a {
display: inline-block;
margin-right: 5px;
}
.post .post-content h3 span {
font-weight: normal;
font-size: 14px;
display: inline-block;
color: #aaaaaa;
}
.post .post-content p { margin: 0 }
.post .discuss {
display: block;
float: right;
margin-top: 7px;
}
.comments {
list-style-type: none;
margin: 0;
}
.comments li h4 {
font-size: 16px;
http://pt.discovermeteor.com/pdf
16/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
margin: 0;
}
.comments li h4 .date {
font-size: 12px;
font-weight: normal;
}
.comments li h4 a { font-size: 12px }
.comments li p:last-child { margin-bottom: 0 }
.dropdown-menu span {
display: block;
padding: 3px 20px;
clear: both;
line-height: 20px;
color: #bbb;
white-space: nowrap;
}
.load-more {
display: block;
border-radius: 3px;
background: rgba(0, 0, 0, 0.05);
text-align: center;
height: 60px;
line-height: 60px;
margin-bottom: 10px;
}
.load-more:hover {
text-decoration: none;
background: rgba(0, 0, 0, 0.1);
}
Commit23
Ver no GitHub
http://pt.discovermeteor.com/pdf
Lanar Instncia
17/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
UmanotasobreCoffeeScript
Neste livro n
Meteor te d cobertura
seguir
Mas se voc
preferir CoffeeScript
http://pt.discovermeteor.com/pdf
18/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Deployment
2.5
SIDEBAR
ficar perfeito
Se voc
enquanto outros
se voc
sinta se livre
s te damos cobertura
livre para usar cada uma delas em qualquer estgio do seu processo de desenvolvimento
Vamos comear
Sinta se
seja
IntroduzindoBarrasLaterais
Este
Ento se voc
picos gerais
.
,
voc
pode seguramente
ImplementandocomMeteor
e a primeira que n
aplicativo em Meteor
bem simples
e digite
http://meuaplicativo.meteor.com a
s vamos tentar
Implementando em Meteor
vulgo
v ao diret
rio do seu
http://pt.discovermeteor.com/pdf
19/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Claro
voc
ctrl+c
uma senha
meuaplicativo
Se isso ocorrer
ap
http://meuaplicativo.meteor.com .
ProteocomSenha
Por padro
Ento voc
ir querer por uma senha para proteger o seu nome de dom nio com a opo
provavelmente
-p , como
abaixo
Voc
e da
pode checar a documentao oficial para mais informao sobre essas coisas como
ou como configurar um
ImplementandoemModulus
Modulus
uma
provedores PaaS
- --
platform as a service
um dos poucos
e j h vrias
http://pt.discovermeteor.com/pdf
20/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Demeteorizer
a qual
s ento
$ modulus login
(
):
tamb
O pr
ximo passo ser criar um banco de dados MongoDB para o nosso aplicativo
prio Modulus
MongoHQ ou com
database
>
),
Administration
http://pt.discovermeteor.com/pdf
,
n
s podemos pegar a
v ao Dashboard
>
MONGO_URL
Databases
>
para o nosso
Select your
21/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Agora
$ modulus deploy
Cheque a documentao do
e SSL
MeteorUp
es na nuvem t
pr
.
es
Ento at
hoje
implementar no seu pr
prio
questo
implementar voc
mesmo no
to simples
especialmente se voc
nica
est
Meteor Up
ou a abreviao
utilitrio da linha de comando que toma conta da configurao e implementao para voc
,
n
voc
instncias de graa
$5
por m
ou AWS
do
o qual prov
).
Micro
mas se voc
servidor
um login
seguro
normalmente
escolher
root
ou
voc
deve ter tr
s coisas
o endereo de IP do seu
as em algum lugar
http://pt.discovermeteor.com/pdf
22/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
IniciandoMeteorUp
Para comear
,
n
npm
como a seguir
rio especial
rep
sitorio Git
Segundo
es
primeiro
especialmente se voc
usando m
rio
digos p
blico
rios separados
es Meteor Up em paralelo
es do nosso
ltiplos diret
ltiplas configura
Isso ser
por exemplo
$ mkdir ~/microscope-deploy
$ cd ~/microscope-deploy
$ mup init
CompartilhandocomDropbox
configura
es de implementao
seu Dropbox
ConfiguraodoMeteorUp
: mup.json
settings.json .
http://pt.discovermeteor.com/pdf
23/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
mup.json
settings.json
tokens
ximo passo
gerado por
es relacionadas ao aplicativo
..
etc
O pr
ter as configura
es relacionadas implementao
enquanto
OAuth tokens
analytics
padro
//configure environmental
"env": {
"ROOT_URL": "http://supersite.com"
}
mup json
es
Autentificao do Servidor
Voc
( ),
PEM
ento ele pode ser usado com quase qualquer provedor em nuvem
Nota Importante
voc
instalou o
se voc
sshpass
http://pt.discovermeteor.com/pdf
antes
).
24/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Configurao MongoDB
O pr
ximo passo
j que eles
Se voc
MONGO_URL
ambiental
Meteor Up
no bloco
apenas defina
setupMongo
defina
env
de
setupMongo
como
false
e adicione a varivel
como
true
Caminho Meteor Up
rio
o qual voc
s precisaremos apontar
pwd
pelo terminal
Variveis Ambientais
Voc
dentro do bloco
env .
tais como
ROOT_URL ,
ConfigurandoeImplementando
Antes de n
s implementarmos
complexo em um
nico comando
$ mup setup
rede
com
Ap
s o sucesso da instalao
http://pt.discovermeteor.com/pdf
25/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
$ mup deploy
s configuramos
MostrandoLogs
emular o comando
$ mup logs -f
visitar o reposit
,
n
s sugerimos
Estas tr
dos casos
Claro
,
n
http://pt.discovermeteor.com/pdf
Mas isto
um t
26/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Templates
dentro
Em outras palavras
burra
com
no subsequentes trabalhos
dentro do diret
rio
client
Vamos criar um novo arquivo chamado main html dentro de nosso diret
preench
lo com o seguinte c
digo
rio
client
e vamos
<head>
<title>Microscope</title>
</head>
<body>
<div class="container">
<header class="navbar">
<div class="navbar-inner">
<a class="brand" href="/">Microscope</a>
</div>
</header>
<div id="main" class="row-fluid">
{{> postsList}}
</div>
</div>
</body>
uma
nica tag
Como voc
pode ver
Por enquanto
MeteorTemplates
http://pt.discovermeteor.com/pdf
27/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
No seu mago
,
e
nossos templates
dentro de
/views
/views
rio
dentro de
s tamb
/posts
m criaremos
FindingFiles
O Meteor
digo no diret
rio
colocou o seu
lo e compil lo corretamente
Isto tamb
mesmo diret
rio
melhor que mantemos as coisas bem organizadas e utilize uma estrutura clara de
arquivos
Dentro de
<template name="postsList">
<div class="posts">
{{#each posts}}
{{> postItem}}
{{/each}}
</div>
</template>
list html
post_item.html :
http://pt.discovermeteor.com/pdf
28/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
<template name="postItem">
<div class="post">
<div class="post-content">
<h3><a href="{{url}}">{{title}}</a><span>{{domain}}</span></h3>
</div>
</div>
</template>
/ _
Note o atributo
item html
name="postList"
do elemento template
Este
simplesmente HTML
blocos de ajuda
com a adio de tr
).
s coisas
parciais
partials
),
Handlebars
express
es
expressions
block helpers
Express
o Handlebars
es tais como
{{title}}
no nosso caso
postItem .
ou retornam o
).
logo mais
sobre isso
Finalmente
blocos de ajuda so tags especiais que controlam o fluxo do template tais como
{{#each}}...{{\each}}
ou
{{#if}}...{{\if}} .
IndoAlm
Voc
aqui
http://pt.discovermeteor.com/pdf
29/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Primeiro
no template
com o
bloco de ajuda
postItem .
template
e n
title
Boa pergunta
em si mesmo
bem direto
Apenas usa tr
ajudante do template
se origina
postItem
O template
{{ }}
posts
s mencionamos
"
s express
{{domain}}
: {{url}}
es
que chama um
ajudantes do template
GerentesdeTemplate
At
agora n
ou at
),
templates e as l
necessrio um gerente
Em outras palavras
o template
Voc
o Meteor mant
gerente
m os
pode pensar em um
seus dados
e prepara eles
.
,
aquele que faz todo o trabalho pesado atribuindo valores para cada uma dessas
variveis
http://pt.discovermeteor.com/pdf
30/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Gerentes?
Quando n
s perguntarmos por a
chamam esses
e como a sigla
Javascript
no
metade respondeu
Gerentes no so de fato
gerentes de template
metade respondeu
MVC
e a outra
digo JavaScript
controllers
AAOECMCJ
controllers
muito atraente
digo
es
Como ainda precisvamos usar um nome para indicar aquilo a que estvamos nos
referindo
gerente
template
dentro do diret
rio
/client/views/posts
. .
js
posts_list.js
var postsData = [
{
title: 'Introducing Telescope',
author: 'Sacha Greif',
url: 'http://sachagreif.com/introducing-telescope/'
},
{
title: 'Meteor',
author: 'Tom Coleman',
url: 'http://meteor.com'
},
{
title: 'The Meteor Book',
author: 'Tom Coleman',
url: 'http://themeteorbook.com'
}
];
Template.postsList.helpers({
posts: postsData
});
http://pt.discovermeteor.com/pdf
list js
31/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Se voc
Nossoprimeirotemplatecomdadosestticos
Commit31
Ver no GitHub
array
Lanar Instncia
- (
trapaceando
Template.myTemplate.helpers()
posts
aguarde at
posts
o pr
s estamos
Definir o ajudante
postsData .
significa que ele agora estar dispon vel para ser usado pelo nosso
template
http://pt.discovermeteor.com/pdf
32/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
<template name="postsList">
<div class="posts">
{{#each posts}}
{{> postItem}}
{{/each}}
</div>
</template>
list html
Agora ser poss vel que nosso template itere sobre o array
postsData
postItem .
Ovalordothis
post_item.js
Template.postItem.helpers({
domain: function() {
var a = document.createElement('a');
a.href = this.url;
return a.hostname;
}
});
/ _
item js
Commit32
Definio do ajudante
domain
Ver no GitHub
pattern
domain
e mais
no
til
no template
postItem
`.
Lanar Instncia
um array
nima
Esse
teste anteriores
http://pt.discovermeteor.com/pdf
33/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Exibindoosdomniosdecadalink.
O ajudante
Javascript
domain
Mas
recebe uma URL e retorna seu dom nio utilizando um pouco da mgica do
pra comear
O ajudante
{{#each}}
posts_list.html .
m atribui o valor do
this
Agora n
s entendemos o porque do
s usarmos
{{title}}
http://pt.discovermeteor.com/pdf
{{url}}
this.title
this.url
( post_item.js ).
this.url
E al
m disso
se
post_item.html , o Meteor
34/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
MgicadoJavascript
dessa pequena
(a)
,
.
Primeiro
href
s estamos criando
ria
como n
).
s j vimos
Por
descrita acima
this
mgica do Javascript
ltimo
especial chamada
hostname
restante da URL
Se voc
navegador
Essa lista
ximo
cap tulo
RecarregamentoAutomticodeCdigo
Voc
deve ter notado que no precisa nem recarregar a janela do seu navegador
rio do seu
O recarregamento automtico de c
digo do Meteor
bem esperto
Ele at
preserva o
http://pt.discovermeteor.com/pdf
35/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
UsandoGit&GitHub
GitHub
verso
tamb
um reposit
3.5
SIDEBAR
um
Mas
,
n
s vamos passar
Descubra Meteor
e que voc
Se voc
j est
SendoCommitted
rio git
um commit
Voc
Ao inv
o c
Por exemplo
isto
o que o
http://pt.discovermeteor.com/pdf
e voc
s tiramos estes
36/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
AGitcommitasshownonGitHub.
O que voc
aqui
(
diff
de
difference
do princ pio
do arquivo
Neste caso
s criamos o arquivo
post_item.js
Modifyingcode.
Desta vez
E claro
s vezes voc
digo
mas deletando
as
http://pt.discovermeteor.com/pdf
37/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Deletingcode.
Ento n
ProcurandoumCdigodeCommit
A vista commit do Git nos mostra as mudanas inclu das neste commit
.
s
Quando voc
clique no boto
Browse code
http://pt.discovermeteor.com/pdf
38/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
TheBrowsecodebutton.
Voc
agora ter acesso ao repo como ele est num commit espec fico
Therepositoryatcommit32.
http://pt.discovermeteor.com/pdf
normal
mas voc
39/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
diferente
Therepositoryatcommit142.
AcessandoUmCommitLocalmente
se voc
Por exemplo
voc
Mas e
localmente num espec fico commit para ver como ele deveria se comportar neste ponto do
processo
instalado
Ento clone
Microscope com
bem
com o
em outras palavras
baixe a c
pia localmente
o reposit
rio do
Esse
github_microscope
http://pt.discovermeteor.com/pdf
no final
j tem um diret
rio
microscope
pre existente
40/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Vamos
cd
linha de comando
).
git :
$ cd github_microscope
Agora quando n
s clonamos o reposit
significa que n
Felizmente
outros
rio GitHub
s estamos olhando o c
digo do
,
n
s baixamos todo o c
digo do app
o que
ltimo commit
selecionar
importa
s estamos no
detached HEAD
onde o Git se
Voc
Isto
seria mais como um viagem do tempo voltando no tempo e possivelmente pisando numa
borboleta
http://pt.discovermeteor.com/pdf
).
41/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
voc
tagged
ou identificador
Voc
nico
Findingacommithash.
s da tag
E finalmente
presente
e se n
42/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
processo
update
at
pode tamb
meteor
quando em estado
detached HEAD
Voc
em qualquer ponto do
j que o c
mrt
PerspectivaHistrica
que voc
mudou
Voc
voc
A questo
voc
Primeiro
ria do GitHub
rio no GitHub
voc
encontrar o certo
mas h
.
ento encontre o boto
History
GitHubsHistorybutton.
Voc
agora tem uma lista arrumada de todos os commits que afetaram este arquivo em
particular
http://pt.discovermeteor.com/pdf
43/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Displayingafileshistory.
OJogodaCulpa
Para finalizar
GitHubsBlamebutton.
http://pt.discovermeteor.com/pdf
44/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Esta vista arrumada nos mostra linha por linha quem modificou o arquivo
em outras palavras
e em cada commit
):
GitHubsBlameview.
Agora
Git
pouquinho ser
http://pt.discovermeteor.com/pdf
e o GitHub tamb
Na verdade
-,
ento n
s no
s mal arranhamos a
Mas felizmente
at
mesmo este
45/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Collections
,
n
a sincronizao
,
n
a Meteor Collection
queremos
desses
tens de
e observaremos a operao
.
N
s chamaremos cada um
post
Naturalmente
Ento
especialmente Mongo
cont
diferente
atrav
por exemplo
nica
Por can
Uma coleo
s de publica
es e assinaturas
um tipo de estrutura de
o banco de
posts.js
dentro dela
nica
dados Mongo
o servidor
Esta informao
),
ria persistente
collections/
Ento adicione
Posts
na ra z do seu aplicativo
Se voc
ento
ainda
e ento um arquivo
http://pt.discovermeteor.com/pdf
46/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
collections posts js
Commit41
Added a posts collection
Ver no GitHub
Posts
Ento a coleo
Lanar Instncia
client/
server/
ou
Entretanto
o que a
bem diferente
UsarVarOuNoUsarVar?
Em Meteor
a palavra chave
var
Posts
porqu
No servidor
de dados padro
Neste sentido
No cliente entretanto
nica
var .
Aqui
este
e ler e
a coleo
uma c
constantemente e
ConsolevsConsolevsConsole
,
n
cada um deles
Terminal
http://pt.discovermeteor.com/pdf
47/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
TheTerminal
Lado do Servidor
console.log()
: $.
Prompt
Tamb
m conhecido por
Shell
Bash
ConsoledoNavegador
TheBrowserConsole
Lado do Cliente
http://pt.discovermeteor.com/pdf
console.log()
executa c
digo JavaScript
.
48/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Prompt
Tamb
m conhecido por
JavaScript Console
DevTools Console
MongoShell
TheMongoShell
s de
meteor mongo .
: >.
Prompt
Tamb
m conhecido por
parte do comando
prompt
voc
E voc
Mongo Console
( $ , ,
>
ou
como
ColeesdoLadodoServidor
No servidor
servidor
a coleo atua como uma API dentro do seu banco de dados Mongo
meteor
comando
meteor mongo
http://pt.discovermeteor.com/pdf
Posts.insert()
),
e v at
digo do
ou
No c
o diret
rio do aplicativo
no qual voc
enquanto o
Ento
rode o
49/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Mongo
e como costumeiramente
exemplo
voc
ctrl+c . Por
MongonoMeteor.com
*.
meteor com
digitando
voc
tamb
voc
pode tamb
A sintaxe do Mongo
familiar
.
N
s no faremos
mas n
ColeesdoLadodoCliente
Cole
Meteor.Collection('posts');
no cliente
o que voc
cliente ser um
informao
cache
est criando
Quando n
declara
Posts = new
m um subconjunto da sua
Em geral
Quando voc
http://pt.discovermeteor.com/pdf
at
mesmo porque n
50/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Segundo
).
basicamente instantneo
ria do navegador
o que significa
o servidor ou ao
Posts.find()
chama
no cliente
carregada
IntroduzindoMiniMongo
No
e voc
De qualquer forma
todas
ComunicaoClienteServidor
Ao inv
Ento
documento que n
).
no nosso caso
uma
( 'posts'
Neste ponto
s devemos ver um
s contextos
nico
> db.posts.find();
{title: "A new post", _id: ObjectId("..")};
http://pt.discovermeteor.com/pdf
51/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Posts.findOne();
Posts.find().count();
Posts.insert({title:
'xxx'
Posts.find().count();
2
Sem surpresas
db.posts.find();
Como voc
pode ver
escrevermos uma
nica linha de c
estritamente falando
s escrevemos uma
nica linha de c
digo
o servidor
: new
sem n
bem
Posts.find().count();
http://pt.discovermeteor.com/pdf
52/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Mesmo apesar de n
atualiza
es
tornar mais
e n
O que acontece
e instantaneamente tamb
que a nossa coleo do lado do servidor foi informada pela nossa coleo do
to
o banco de dados
post
es
conectadas
til assim
.
N
tipo
MantendoemTempoReal
tela
es no console do browser
a informao
uma coisa
Fazendo isto n
esttico
mas o que
na
udo
PovoandooBancodeDados
s faremos
Posts
.
N
s o faremos
Primeiro
.
N
s usaremos
meteor
reset , o qual apaga seu banco de dados e reseta seu projeto. Claro, voc ir querer ser bem
cuidadoso com este comando uma vez que voc
http://pt.discovermeteor.com/pdf
53/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
real
pressionando
ctrl-c
e ento
na linha de comando
rode
$ meteor reset
desenvolvimento
um comando
til em
estado inconsistente
carregar tr
s podemos adicionar o c
Posts
vazia
if (Posts.find().count() === 0) {
Posts.insert({
title: 'Introducing Telescope',
author: 'Sacha Greif',
url: 'http://sachagreif.com/introducing-telescope/'
});
Posts.insert({
title: 'Meteor',
author: 'Tom Coleman',
url: 'http://meteor.com'
});
Posts.insert({
title: 'The Meteor Book',
author: 'Tom Coleman',
url: 'http://themeteorbook.com'
});
server fixtures js
http://pt.discovermeteor.com/pdf
54/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Commit42
Ver no GitHub
navegador de usurio
insert
chamadas
rio
Lanar Instncia
O c
e far
de dados
meteor,
e estes tr
ConectandoainformaoaonossoHTMLcomajudantes
Agora
se n
s veremos tr
s posts carregados no
MiniMongo
Posts.find().fetch();
Browser console
Cap tulo
No
3
n
s vimos como o Meteor nos permite ligar um contexto de informao aos nossos
Falando nisso
posts_list.js
postsData
digo
.
N
s apenas
http://pt.discovermeteor.com/pdf
55/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Template.postsList.helpers({
posts: function() {
return Posts.find();
}
});
list js
Commit43
Wired collection into
postsList
Ver no GitHub
template
Lanar Instncia
Encontre&Traga
, find()
No Meteor
Quando n
retorna um cursor
que
udo
fetch()
no
Dentro do aplicativo
o Meteor
de voc
fetch()
no ver
Agora
ao inv
).
ncia em c
digo de Meteor
Esta
razo
e o porqu
de
nosso navegador
Se n
s voltarmos ao
s vemos
http://pt.discovermeteor.com/pdf
56/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Usinglivedata
Ento n
nosso
{{#each}}
Agora
s do console
Posts.insert({
Browser console
http://pt.discovermeteor.com/pdf
voc
57/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Addingpostsviatheconsole
Voc
quanto a mudanas
Quando n
s diss
mos ao
correta na tela
InspecionandomudanasnoDOM
Neste caso
<div
aconteceu
posts existentes
Agora
voc
ter o mesmo
correspondente a um dos
no console JavaScript
inspector
<div>
ver um
<div>
<div>
extra
Quando voc
voltar ao
existente selecionado
Isto
uma forma
mais voc
ainda
ConectandoColees:PublicaeseAssinaturas
http://pt.discovermeteor.com/pdf
58/261
1/8/2015
At
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
ento
produo
autopublish
s t nhamos o pacote
compartilhada na
ativado
es em
Isto no
e digite
Se voc
Isto
porque n
voc
autopublish
s estvamos dependendo do
para assegurar que a nossa coleo de posts do lado do cliente fosse um espelho de todos os
Eventualmente n
enquanto
,
n
lo
s apenas configuraremos o
todos os posts
).
Posts
Para faz
publish()
Mas por
ntegra
Meteor.publish('posts', function() {
return Posts.find();
});
server publications js
No cliente
ao
.
N
main.js :
Meteor.subscribe('posts');
http://pt.discovermeteor.com/pdf
59/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
client main js
Removed
Commit44
autopublish
Ver no GitHub
Se n
Lanar Instncia
Ufa
Concluso
Ento o que n
o que n
s alcanamos
s temos agora
Internet
Bem
apesar de n
rias e v
las aparecer
http://pt.discovermeteor.com/pdf
60/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
PublicaeseSubscries
Publica
es e subscri
as aplica
4.5
SIDEBAR
inseguro
ou que
Uma grande parcela do motivo das pessoas inicialmente acharem estes conceitos um pouco
confusos
mgica
).
fazer
,
til
ela pode
Ento vamos analisar as camadas dessa mgica e entender o que est acontecendo
OsVelhosTempos
Mas primeiro
aplicao
o cliente
ltimos
20
i e seu navegador
12
tweets de Bob
e por ai vai
Voc
Na metfora da livraria
View Controller
Finalmente
basicamente
).
Esta
).
a parte
os
um
pediu
Isso
atendente de livraria navegando entre os corredores para encontrar o livro que voc
Quando
(.
2011
View
viso vista
a aplicao pega o c
http://pt.discovermeteor.com/pdf
O trabalho da
61/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
aplicao
finalizado
xima requisio
OCaminhodoMeteor
inovao do Meteor
Como vimos
a principal
aplicativo Meteor inclui um componente no lado do cliente que vai rodar no cliente
navegador
).
um
Colocandoumsubgrupodobancodedadosnocliente.
Isso
at
em casa e l
http://pt.discovermeteor.com/pdf
noite
mas tamb
m te segue
).
62/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Simplesmente
:
es
primeira
dado na rede
).
Segundo
voc
ao inv
s de mandar c
data on the
).
lat
).
Meteor vai pegar uma parte do seu banco de dados e copi lo para o cliente
wire
latency compensation
compensao de
ncia
Publicao
por raz
es de segurana e escabilidade
Ento vamos precisar de uma forma de dizer ao Meteor quais subgrupos de dados podem ser
enviados ao cliente
s de uma publicao
dados
http://pt.discovermeteor.com/pdf
63/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Todosospostscontidosnonossobancodedados.
(.
i e enviados ao cliente
).
Vamos dizer ao Meteor que desejamos publicar apenas os posts sem marca
http://pt.discovermeteor.com/pdf
es
64/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Excluindopostsmarcados.
Aqui temos o c
digo correspondente
// no servidor
Meteor.publish('posts', function() {
return Posts.find({flagged: false});
});
Isso assegura para que no exista uma forma de um cliente estar apto a acessar post
marcados
Isso
cliente
http://pt.discovermeteor.com/pdf
apenas
65/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
DDP
Fundamentalmente
voc
como um funil que transfere dados de uma coleo no lado do servidor para uma
O protocolo que
Protocol
chamado DDP
).
pode assistir essa palestra da Real Time Conference por Matt DeBergalis
fundadores do Meteor
),
voc
um dos
por
Subscrio
Mesmo que seja nossa inteno deixar qualquer publicao no marcada dispon vel para os
clientes
es de uma vez
.
N
precisamos de uma forma para os clientes especificarem qual subgrupo de dados eles
es entram
Por exemplo
vamos dizer que estamos atualmente navegando na pgina perfil de Bob Smith
http://pt.discovermeteor.com/pdf
66/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
SubscrevendonospostsdeBobirespelhlosnocliente.
Primeiro
// no servidor
Meteor.publish('posts', function(author) {
return Posts.find({flagged: false, author: author});
});
E podemos ento definir este parmetro quando nos subscrevermos nesta publicao no
// no cliente
Meteor.subscribe('posts', 'bob-smith');
Assim
atualmente
Dessa forma
voc
voc
Ao inv
s de se
precisa
http://pt.discovermeteor.com/pdf
67/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Encontrando(finding)
JavaScript
mem
,
ria
Ruby
mas n
).
Python
tiplas categorias
( )
encontrar
find
por exemplo
aparece
JavaScript
por agora
Selecionandoumsubgrupodedocumentosnocliente.
,
n
Posts.find()
para
// no cliente
Template.posts.helpers({
posts: function(){
return Posts.find(author: 'bob-smith', category: 'JavaScript');
}
});
Agora que n
funcionam
http://pt.discovermeteor.com/pdf
es e subscri
es comuns de implementao
es
.
68/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
PublicaoAutomtica(autopublishing)
Se voc
automaticamente o pacote
(.
i e usando
autopublish
ativado
Para comear
exatamente faz
O objetivo do
aplicao Meteor
para o cliente
es e subscri
es para voc
Autopublish
http://pt.discovermeteor.com/pdf
'posts'
no servidor
.
69/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
autopublish
Ento
Se voc
estiver usando
existem problema
'posts'
no cliente
).
),
Claro
autopublish
est comeando
e ainda
es
PublicandoColeesCompletas
remova o
los novamente
Por exemplo
duplicando o
Meteor.publish('allPosts', function(){
return Posts.find();
});
http://pt.discovermeteor.com/pdf
70/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Publicandoumacoleocompleta
Comments
mas
es completas
es publicamos ou no
Neste caso
Posts
no
PublicandoColeesParcialmente
O pr
http://pt.discovermeteor.com/pdf
71/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Meteor.publish('somePosts', function(){
return Posts.find({'author':'Tom'});
});
Publicandoumacoleoparcialmente
http://pt.discovermeteor.com/pdf
72/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
NosBastidores
Se voc
es de se usar
A razo
added()
isso
para configurar os
voc
ready()
todos
retornar um cursor
ncia
o m
todo
Talvez no diretamente
( . . Posts.find({'author':'Tom'}) )
i e
mas se voc
em uma funo de
Quando o Meteor v
_publishCursor()
tamb
voc
somePosts
que a publicao
adivinhou
retornou um cursor
ele chama
automaticamente
Aqui o que o
_publishCursor()
faz
).
.added()
Usando
para fazer
isso
cursor e
.added() , .changed()
No exemplo acima
removido ou alterado
.removed()
Ele usa
ele envia
.observe()
no
).
cliente
PublicandoPropriedadesParciais
Como anteriormente
mas n
s podemos continuar
vamos usar
find()
http://pt.discovermeteor.com/pdf
73/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Meteor.publish('allPosts', function(){
return Posts.find({}, {fields: {
date: false
}});
});
Publicandopropriedadesparciais
Claro
s tamb
cnicas
Por exemplo
assim
se n
s quisermos
podemos escrever
http://pt.discovermeteor.com/pdf
74/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Meteor.publish('allPosts', function(){
return Posts.find({'author':'Tom'}, {fields: {
date: false
}});
});
Resumindo
cole
es
com
autopublish
at
es
es no Meteor
e estas simples
As vezes
voc
vai precisar ir al
http://pt.discovermeteor.com/pdf
m combinando
es
s vamos
75/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Rotas
),
utilizadores
s gostar amos que essas pginas pudessem ser acess vel atrav
http://myapp.com/posts/xyz
no formato
onde
s de um permalink
um URL
de MongoDB
Isto significa que vamos precisar de algum tipo de roteamento para ler o que est na barra de
do correto
AdicionandooPacoteIronRouter
Iron Router
es
Meteor
Este no s
tratar de filtros
associar a
ou seja
). (
.)
),
especificar caminhos
Nota
como tamb
m permite
es
controlar
Primeiro
Consola
processo
e depois
mrt
http://pt.discovermeteor.com/pdf
pronto a usar
usando
ctrl+c
Note que
para matar o
76/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
poder instalar
um pacote de terceiros
ou seja
).
no vai funcionar
VocabulriodeRoteador
N
s vamos falar de vrias caracter sticas diferentes do roteador neste cap tulo
voc
Caso contrrio
Se
j estar
segue se um pequeno
glossrio
Rotas
Uma rota
Bsicamente
um conjunto de
instru
um URL
.
/terms_of_service
/posts/xyz ,
/search?keyword=meteor .
Caminhos
esttico
Um caminho
parmetros de pesquisa
Segmentos
frente
( / ).
:
Ganchos
ou dinmico
Ganchos so a
es que voc
e ainda incluir
depois ou at
Filtros
Templates de Rota
especifique um
por omisso
Layout
cont
m todo o c
Controlador
Caso no
Por vezes
voc
Eles
e vai permanecer o
digo
poss vel
nico controlador de
gica de roteamento
GitHub
http://pt.discovermeteor.com/pdf
77/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Roteamento:MapearURLsparaTemplates
At
agora
,
n
tais
como
sempre a mesma
um cabealho
baixo deste
O Iron Router permite nos outra abordagem ao ficar responsvel pelo que
s pr
prios
renderizado
Em vez disso
vamos apontar o
O ajudante
{{yield}}
de agora
{{yield}} .
como conveno
template da rota
):
vamos designar
a partir
Layoutsetemplates.
http://pt.discovermeteor.com/pdf
78/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
<body>
pr
prio template
O nosso
do
, layout.html .
, main.html
<head>
<title>Microscope</title>
</head>
m criado
layout.html
aplicao
<template name="layout">
<div class="container">
<header class="navbar">
<div class="navbar-inner">
<a class="brand" href="/">Microscope</a>
</div>
</header>
<div id="main" class="row-fluid">
{{yield}}
</div>
</div>
</template>
postsList
yield . Repare que depois desta alterao, no vemos nada no ecr. Isto porque ainda no
dissemos ao roteador o que fazer com o URL
Para comear
o template
desta criar
,
n
para
e dentro
router.js :
http://pt.discovermeteor.com/pdf
79/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Router.configure({
layoutTemplate: 'layout'
});
Router.map(function() {
this.route('postsList', {path: '/'});
});
lib router js
Primeiro
postsList
Segundo
definimos uma
/.
Adiretoria /lib
Qualquer coisa que seja colocada dentro da diretoria
/lib garantidamente
).
de pacotes inteligentes
digo de
:
/server ,
Um aviso
/lib
/client
nem de
ambientes
RotascomNome
Por omisso
realidade
URL
ele vai at
path
o Iron Roter vai procurar por um template com o mesmo nome da rota
tiv
),
postsList .
http://pt.discovermeteor.com/pdf
ou seja
Na
se no
80/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Outra d
porque
Dar
nomes a rotas permite nos utilizar algumas caracter sticas do Iron Router que tornam mais
O mais
til
o ajudante Handlebars
{{pathFor}} ,
Queremos que o nosso link principal de casa aponte para a lista de artigos
ajudante ir sempre fazer output do URL correto mesmo que o caminho no roteador seja
alterado
<header class="navbar">
<div class="navbar-inner">
<a class="brand" href="{{pathFor 'postsList'}}">Microscope</a>
</div>
</header>
//...
Commit51
Ver no GitHub
Lanar Instncia
EsperandoporDados
notar que a lista aparece vazia por uns momentos antes dos artigos aparecerem
dos
posts
Isto
),
ir
porque
http://pt.discovermeteor.com/pdf
81/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Por sorte
vamos
waitOn
esperar pela
subscrio
Router.configure({
layoutTemplate: 'layout',
loadingTemplate: 'loading',
waitOn: function() { return Meteor.subscribe('posts'); }
});
Router.map(function() {
this.route('postsList', {path: '/'});
});
lib router js
Primeiro
modificmos o bloco
Segunda
tamb
Router.configure()
posts
waitOn
esta sequ
ncia apenas vai acontecer uma vez quando o utilizador acede sua aplicao pela
primeira vez
Depois disso
E como n
com segurana do
Normalmente
utilizao
main.js
).
mas tamb
voc
la
ncia de
http://pt.discovermeteor.com/pdf
es
82/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
coisa que
o template de carregamento
spin
para criar
da seguinte forma
<template name="loading">
{{>spinner}}
</template>
Note que
fora
da nossa aplicao
,
n
template
Commit52
Ver no GitHub
http://pt.discovermeteor.com/pdf
Lanar Instncia
83/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
UmPrimeiroOlharSobreAReatividade
Reatividade
abordado o t
pico
mas como
redirecionar o utilizador de volta para a pgina correta assim que os dados foram
carregados
Por agora
por aqui
Mas no se preocupe
e ficar
RoteandoParaUmPostEspecfico
os detalhes de um
nico artigo
:
n
Neste caso
Para comear
j que
e fazer
<template name="postPage">
{{> postItem}}
</template>
/ _
page html
),
comentrios
mas por agora este vai servir simplesmente como um contentor para a nossa
http://pt.discovermeteor.com/pdf
84/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
{{> postItem}} .
incluso
para o template
/posts/<ID>
postPage :
Router.map(function() {
this.route('postsList', {path: '/'});
this.route('postPage', {
path: '/posts/:_id'
});
});
lib router js
A sintaxe especial
rota na forma
:_id
/posts/xyz/ , onde
xyz
xyz
primeiro
Segundo
_id
na lista
params
do
roteador
_id
O roteador no tem
caracteres
sabe o
como
_id
o roteador
Ento
Felizmente
dados do template
De forma simples
template
http://pt.discovermeteor.com/pdf
85/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Ocontextodedados.
No nosso caso
_id
usando o
Router.map(function() {
this.route('postsList', {path: '/'});
this.route('postPage', {
path: '/posts/:_id',
data: function() { return Posts.findOne(this.params._id); }
});
});
lib router js
Assim
uma pesquisa
Lembre se que
findOne
http://pt.discovermeteor.com/pdf
_id
devolve um
como argumento
um atalho para
{_id:
86/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
id} .
Dentro da funo
e podemos utilizar
data
dados em portugu
this.params
, this
dentro da nossa
path .
partes que
MaisSobreContextodeDados
this
Isto
{{#each}} , que
interao
{{#each widgets}}
{{> widgetItem}}
{{/each}}
Mas tamb
{{#with}} , que
simplesmente diz
podemos escrever
Por exemplo
{{#with myWidget}}
{{> widgetPage}}
{{/with}}
Tamb
da chamada ao template
Ou seja
o bloco anterior de c
como
http://pt.discovermeteor.com/pdf
87/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
UtilizandoUmAjudantedeRoteadorComNomeDinmico
Por fim
temos de ter a certeza que estamos a apontar para o lugar certo quando queremos
Novamente
<a
'postPage'}} :
<template name="postItem">
<div class="post">
<div class="post-content">
<h3><a href="{{url}}">{{title}}</a><span>{{domain}}</span></h3>
</div>
<a href="{{pathFor 'postPage'}}" class="discuss btn">Discuss</a>
</div>
</template>
/ _
item html
Commit53
Rotear para uma
Ver no GitHub
Mas espera
como exatamente
/posts/xyz
Na realidade
Assim
_id
xyz
em
_id .
de alguma esp
cie
dados do ajudante
Lanar Instncia
precisa de um
No final de contas
o Iron Router
prio
_id
no local mais l
.
N
path .
o contexto de
http://pt.discovermeteor.com/pdf
88/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
this
nosso
corresponde a um artigo
Alternativamente
tamb
que
!)
surpresa
_id .
ou seja
{{pathFor 'postPage' someOtherPost}} . Um possvel cenrio onde este padro poder ser
usado
Umanicapginadeartigo.
http://pt.discovermeteor.com/pdf
89/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
HTML5pushState
Uma coisa a perceber
HTML
pushState
estado da aplicao
es necessrias ao
facto
De
s vezes as coisas mudam to rpido que pode ser necessria uma transio de
pgina
interessante
pico
http://pt.discovermeteor.com/pdf
90/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
ASesso
Meteor
5.5
SIDEBAR
um framework reativo
O que significa
coisas
mudam
extremamente
es
AMeteorSession
Agora no Microscope
voc
).
e o banco de dados
).
escondido
A Session
global
A Session
por exemplo
h uma sesso
e ela
Ele
relevante a
mero que s
Mudandoa
Esta
sesso
Session
chamar
Session.set('pageTitle',
http://pt.discovermeteor.com/pdf
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Browser console
Voc
reativa de dados
coloc la em um helper
voc
ver a sa da do helper
adiocione o seguinte c
<header class="navbar">
<div class="navbar-inner">
<a class="brand" href="{{pathFor 'postsList'}}">{{pageTitle}}</a>
</div>
</header>
Template.layout.helpers({
pageTitle: function() { return Session.get('pageTitle'); }
});
varveis Session
Session.set()
m disso se n
A different title
HCR
conserva as
na barra de navegao
Se no
novamente
conhecida como
Al
),
Session.set('pageTitle',
Browser console
http://pt.discovermeteor.com/pdf
92/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
lugar da aplicao
exageradamente
MudanasIdnticas
Se voc
Session.set()
um valor id
ntico
o Meteor
evitar a chamada do m
todo
IntroduzindooAutorun
template helper
).
modelo auxiliar
template helpers
e tamb
so inerentemente reativos
a maioria do nosso c
como os
helloWorld = function() {
alert(Session.get('message'));
}
no
reativo
significando que n
alert
feita
mudarmos a varivel
Ai
o c
autorun
vai
rodar automaticamente e continuar rodando toda vez que a fonte de dados reativa usada
mudar
http://pt.discovermeteor.com/pdf
93/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Deps.autorun(
le')); } );
Value is: A brand new title
Console do navegador
o bloco de c
Session.set('pageTitle',
Agora
autorun
Console do navegador
Mgica
todo novamente
do
se n
um bloco
autorun
envolver nosso c
digo em
autorun :
Deps.autorun(function() {
alert(Session.get('message'));
});
HotCodeReload
de nossos arquivos de c
http://pt.discovermeteor.com/pdf
digos
( ).
HCR
informando
94/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Isso
.
,
essa diferena
Session.set('pageTitle', 'A
Session.get('pageTitle');
Browser console
Se n
por exemplo
).
Do outro lado
se
digo
Tente agora
Session.get('pageTitle');
Browser console
Ento se estivermos usando variveis de sesso para rastrear exatamente o que o usurio est
fazendo
as variveis de sesso
es em produo de
nossas aplica
interrompidos
Se n
sesso
http://pt.discovermeteor.com/pdf
95/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Session.get('pageTitle');
null
Browser console
Quando n
s recarregamos a pgina
s perdemos a sesso
Com o HCR
o Meteor salva a
Entretanto
se um
e ele
deseja resetar ao ponto inicial que qualquer usurio vai ver quando visita a URL
As importantes li
1.
2.
dentro da pr
pria URL
http://pt.discovermeteor.com/pdf
96/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
AdicionandoUsurios
At
ento
s at
es demonstrativas e estticas
tipo
Por
es
Na real
e informao inserida
Contas:usuriosdeformasimples
voc
ainda
,
,
Por sorte
Meteor te d cobertura
Claro
Pior
es de
JavaScript
quanto no cliente
JavaScript
HTML
mas no
contribuir com c
),
terceiros
CSS
mas j que n
accounts-ui-bootstrap-dropdown
).
estilizao
no lugar
Na linha de comando
com
no se preocupe
,
a
nica diferena
na
s digitamos
Terminal
Esses dois comandos fazem os templates especiais de conta dispon veis para n
http://pt.discovermeteor.com/pdf
97/261
1/8/2015
podemos inclu
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
exemplo
: {{loginButtons align="right"}} .
align
pode controlar em que lado o seu log in dropdown aparece usando o atributo
inclu remos em
es ao nosso cabealho
).
header
por
prio
(
n
s o
timo
<template name="layout">
<div class="container">
{{>header}}
<div id="main" class="row-fluid">
{{yield}}
</div>
</div>
</template>
<template name="header">
<header class="navbar">
<div class="navbar-inner">
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-col
lapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<a class="brand" href="{{pathFor 'postsList'}}">Microscope</a>
<div class="nav-collapse collapse">
<ul class="nav pull-right">
<li>{{loginButtons}}</li>
</ul>
</div>
</div>
</header>
</template>
http://pt.discovermeteor.com/pdf
98/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Agora
quando n
s vemos os bot
es de login das
MeteorsbuiltinaccountsUI
logar
um username
,
n
config.js
novo arquivo
dentro de
Accounts.ui
num
client/helpers :
Accounts.ui.config({
passwordSignupFields: 'USERNAME_ONLY'
});
http://pt.discovermeteor.com/pdf
99/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Commit61
Added accounts and added template to the header
Ver no GitHub
Lanar Instncia
CriandoNossoPrimeiroUsurio
username
o boto
Sign in
Isto confirma que uma conta de usurio foi criada para voc
Mas de onde a
Ao adicionar o pacote
acessada com
contas , o Meteor criou uma nova coleo especial, a qual pode ser
Meteor.users . Para v
la
Meteor.users.findOne();
Browser console
olhada
voc
identifica voc
tamb
_id
se voc
der uma
que unicamente
Meteor.user() .
segundo usurio
Mas espere
vamos rodar
. Meteor.user()
Meteor.users.find().count();
Browser console
http://pt.discovermeteor.com/pdf
100/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
O console retorna
1.
Espere
no deveria ser
voc
o caso
Mongo
s logaremos no Mongo
( meteor mongo
nico
no seu terminal
Se voc
tentar
o banco de dados
e checaremos
> db.users.count()
2
Mongo console
navegador
UmMistriodaPublicao!
Se voc
4,
talvez voc
A resposta
auto publica
Se no o fizesse
Ento a publicao est apenas publicando um objeto usurio por usurio logado
quando voc
no est logado
http://pt.discovermeteor.com/pdf
).
e nenhum
101/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Ainda mais
no servidor e no cliente
Em Mongo
Para v
la
> db.users.findOne()
{
"createdAt" : 1365649830922,
"_id" : "kYdBd9hr3fWPGPcii",
"services" : {
"password" : {
"srp" : {
"identity" : "qyFCnw4MmRbmGyBdN",
"salt" : "YcBjRa7ArXn5tdCdE",
"verifier" : "df2c001edadf4e475e703fa8cd093abd4b63afccbca48f
ad1d2a0986ff2bcfba920d3f122d358c4af0c287f8eaf9690a2c7e376d701ab2fe1acd53a5bc
3e843905d5dcaf2f1c47c25bf5dd87764d1f58c8c01e4539872a9765d2b27c700dcdedadf5ac
82521467356d3f91dbeaf9848158987c6d359c5423e6b9cabf34fa0b45"
}
},
"resume" : {
"loginTokens" : [
{
"token" : "BMHipQqjfLoPz7gru",
"when" : 1365649830922
}
]
}
},
"username" : "tmeasday"
}
Mongo console
muito reduzido
como voc
pode ver ao
Meteor.users.findOne();
Browser console
http://pt.discovermeteor.com/pdf
102/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Este examplo nos mostra como uma coleo local pode ser um subconjunto seguro do
para funcionar
neste caso
O usurio logado v
).
logar
Este
um padro
til a se aprender
como voc
ver mais
adiante
quiser
Voc
na coleo
no possa tornar p
pode checar o Meteor docs para ver como opcionalmente publicar mais campos
Meteor.users .
http://pt.discovermeteor.com/pdf
103/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Reatividade
Se as cole
til
informao
Ao inv
atrav
ento reatividade
centro
Cole
6.5
SIDEBAR
s de chamadas AJAX
vulgo
mudanas na
informao podem ento vir a qualquer momento e serem aplicadas interface do usurio
sem problemas
o Meteor
O c
atualizada
capaz de
atrav
s desses callbacks
Posts.find().observe({
added: function(post) {
// when 'added' callback fires, add HTML element
$('ul').append('<li id="' + post._id + '">' + post.title + '</li>');
},
changed: function(post) {
// when 'changed' callback fires, modify HTML element's text
$('ul li#' + post._id).text(post.title);
},
removed: function(post) {
// when 'removed' callback fires, remove HTML element
$('ul li#' + post._id).remove();
}
});
Voc
http://pt.discovermeteor.com/pdf
104/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
<li>
da postagem
s comeamos a precisar de m
ltiplas fontes de
Usar observe() ?
Quando
devemos
widgets de terceiros
s vezes necessrio
Por exemplo
s queremos adicionar e
Coleo
digamos
Em tais casos
conversar
exemplo
voc
observe()
voc
dropPin()
).
removePin()
ou
added
removed
para chamar os m
Por
todos
da API do mapa
Umapproachdeclarativo
O Meteor prov
declarativo
a n
reatividade
a qual
em sumo um approach
Sendo declarativo ele nos permite definir a relao entre objetos uma vez e saber
Este
ao inv
.
,
um conceito poderoso
renderizamos HTML baseado em qualquer fonte de informao reativa com que nos
importamos
atualizada
gente escrever
http://pt.discovermeteor.com/pdf
105/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
<template name="postsList">
<ul>
{{#each posts}}
<li>{{title}}</li>
{{/each}}
</ul>
</template>
Template.postsList.helpers({
posts: function() {
return Posts.find();
}
});
observe()
para n
e re
MonitoramentodeDependnciasemMeteor:Computaes
aplicativo em Meteor
reativo
digo
em tempo real
Ento
a reatividade
Em outras palavras
a computao
informao reativa
reativamente a ela
renderiza
por exemplo
voc
es
um bloco de c
digo dentro de um
e n
nem todo c
Se voc
e gostaria de responder
pria computao
).
digo
http://pt.discovermeteor.com/pdf
106/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
invalidate()
Para tanto
na computao
Computa
invalidation
e isto
).
es do template
do template tamb
eficientemente
dos on
es
on invalidation se voc
precisar
ncia
ConfigurandoumaComputao
Agora que n
.
N
es
Deps.autorun
lo reativo
Deps.autorun(function() {
console.log('There are ' + Posts.find().count() + ' posts');
});
, autorun
.
N
J que
depend
que n
s podemos escrever c
http://pt.discovermeteor.com/pdf
.
107/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
http://pt.discovermeteor.com/pdf
108/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
CriandoArtigos
s vimos como
banco de dados
s do console
usando a chamada
Posts.insert
ao
mas n
Eventualmente
,
n
ConstruindoumaNovaPginadeArtigo
Router.configure({
layoutTemplate: 'layout',
loadingTemplate: 'loading',
waitOn: function() { return Meteor.subscribe('posts'); }
});
Router.map(function() {
this.route('postsList', {path: '/'});
this.route('postPage', {
path: '/posts/:_id',
data: function() { return Posts.findOne(this.params._id); }
});
this.route('postSubmit', {
path: '/submit'
});
});
lib router js
do template
data
postPage . Lembre
http://pt.discovermeteor.com/pdf
this
109/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
AdicionandoumLinkaoCabealho
,
n
nosso cabealho
<template name="header">
<header class="navbar">
<div class="navbar-inner">
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-col
lapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<a class="brand" href="{{pathFor 'postsList'}}">Microscope</a>
<div class="nav-collapse collapse">
<ul class="nav">
<li><a href="{{pathFor 'postSubmit'}}">New</a></li>
</ul>
<ul class="nav pull-right">
<li>{{loginButtons}}</li>
</ul>
</div>
</div>
</header>
</template>
mostrar o template
http://pt.discovermeteor.com/pdf
/submit , o Meteor
110/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
<template name="postSubmit">
<form class="main">
<div class="control-group">
<label class="control-label" for="url">URL</label>
<div class="controls">
<input name="url" type="text" value="" placeholder="Your URL"/>
</div>
</div>
<div class="control-group">
<label class="control-label" for="title">Title</label>
<div class="controls">
<input name="title" type="text" value="" placeholder="Name your
post"/>
</div>
</div>
<div class="control-group">
<label class="control-label" for="message">Message</label>
<div class="controls">
<textarea name="message" type="text" value=""/>
</div>
</div>
<div class="control-group">
<div class="controls">
<input type="submit" value="Submit" class="btn btn-primary"/>
</div>
</div>
</form>
</template>
/ _
Note
isto
Bootstrap
submit html
um monte de marcao
assim
m de se usar o Twitter
a marcao extra
http://pt.discovermeteor.com/pdf
111/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Thepostsubmitform
Este
um simples formulrio
.
N
j que
JavaScript
No faz sentido prover um plano reserva sem ser em JS quando se considera que
um aplicativo em Meteor
).
desativado
CriandoArtigos
evento
submit
ao inv
s de digamos um evento
http://pt.discovermeteor.com/pdf
submit
click
do formulrio
),
no boto
melhor usar o
).
112/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Template.postSubmit.events({
'submit form': function(e) {
e.preventDefault();
var post = {
url: $(e.target).find('[name=url]').val(),
title: $(e.target).find('[name=title]').val(),
message: $(e.target).find('[name=message]').val()
}
}
});
post._id = Posts.insert(post);
Router.go('postPage', post);
/ _
submit js
Commit71
Ver no GitHub
Lanar Instncia
Esta funo usa jQuery para analisar os valores dos vrios campos do formulrio
argumento do
event
.
N
e povoar o
preventDefault
no
Finalmente
funo
go()
id
insert()
O resultado em rede
A funo
o artigo
a qual a
s navegarmos at
criado
e o usurio
AdicionandoAlgumaSegurana
http://pt.discovermeteor.com/pdf
113/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
mas n
faam
Claro
rios o
,
n
s podemos
Mesmo assim
um
usurio poderia concebivelmente criar um artigo no console do navegador sem estar logado
s no queremos isso
a questo
que voc
es Meteor
Isso permite
comece facilmente e construa seu aplicativo deixando a parte chata para mais tarde
- !
insecure :
pacote
s removeremos o
Terminal
Ap
s o faz
lo
noc
pacote
artigos
Isto
porque sem o
no so mais permitidas
.
N
PermitindoInseresdeArtigo
Para comear
,
n
cnica diferente
Como de costume
s eventualmente
de novo
http://pt.discovermeteor.com/pdf
114/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
collections posts js
Commit72
Removed insecure
Ver no GitHub
s chamamos
Lanar Instncia
este
dizendo
userId
retorna
clientes t
passada s chamadas
),
o que
allow
quase sempre
.
til
userId .
null
and
deny
ou
E como as contas
userId
estar
sempre correta
http://pt.discovermeteor.com/pdf
voc
Tente
115/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Insertfailed:Accessdenied
Entretanto
,
n
es
).
e no h c
garanta isso
ltiplos artigos podem ser criados que apontem para a mesma URL
ProtegendooAcessoaoFormulriodeNovoArtigo
.
N
roteador toma
Voc
entre
http://pt.discovermeteor.com/pdf
).
ou te recusar
116/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
O que n
s precisamos fazer
renderizar o template
accessDenied
ao inv
e se eles no estiverem
s do esperado template
).
postSubmit
(
n
s ento
Router.configure({
layoutTemplate: 'layout'
});
Router.map(function() {
this.route('postsList', {path: '/'});
this.route('postPage', {
path: '/posts/:_id',
data: function() { return Posts.findOne(this.params._id); }
});
this.route('postSubmit', {
path: '/submit'
});
});
var requireLogin = function() {
if (! Meteor.user()) {
this.render('accessDenied');
this.stop();
}
}
Router.before(requireLogin, {only: 'postSubmit'});
lib router js
s tamb
<template name="accessDenied">
<div class="alert alert-error">You can't get here! Please log in.</div>
</template>
http://pt.discovermeteor.com/pdf
denied html
117/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Commit73
Ver no GitHub
Se voc
tentar ir a http
//
Lanar Instncia
:3000
localhost
submit
voc
Theaccessdeniedtemplate
usurio loga
muda instantaneamente de
escrever nenhum c
Logue
accessDenied
para
ou similares
quando o
postSubmit
sem que n
s precisemos
Voc
http://pt.discovermeteor.com/pdf
que o
sequer
118/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
existe
voc
que
),
ou no
At
corretas
e n
accessDenied
ou o template
postSubmit
at
que saibamos
Ento n
Meteor.loggingIn()
seja verdadeiro
Router.map(function() {
this.route('postsList', {path: '/'});
this.route('postPage', {
path: '/posts/:_id',
data: function() { return Posts.findOne(this.params._id); }
});
this.route('postSubmit', {
path: '/submit'
});
});
var requireLogin = function() {
if (! Meteor.user()) {
if (Meteor.loggingIn())
this.render(this.loadingTemplate);
else
this.render('accessDenied');
this.stop();
lib router js
http://pt.discovermeteor.com/pdf
119/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Commit74
Ver no GitHub
Lanar Instncia
EscondendooLink
A maneira mais fcil de prevenir que os usurios cheguem a esta pgina por engano quando
<ul class="nav">
{{#if currentUser}}<li><a href="{{pathFor 'postSubmit'}}">Submit Post</a><
/li>{{/if}}
</ul>
Commit75
Ver no GitHub
O ajudante
currentUser
nos
Lanar Instncia
accounts
o handlebar equivalent de
MtodoMeteor:AbstraoeSeguranaMelhores
que tais usurios criem artigos mesmo que eles trapaceiem e usem o console
http://pt.discovermeteor.com/pdf
Por
e negar
m ainda h
:
120/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Timestamping os artigos
Assegurar que uma mesma URL no seja publicada mais que uma vez
Voc
ID
username
..
etc
evento
Para a timestamp
usurio
),
mais tarde
Finalmente
apesar que n
cliente
es
es e atualiza
es bsicas coleo
se n
usemos um
todo
Um M
todo Meteor
update
remove
Vamos voltar a
da
Coleo
alis
todos
so todos M
as fun
es
insert ,
prio
chamaremos um M
todo chamado
http://pt.discovermeteor.com/pdf
post :
121/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Template.postSubmit.events({
'submit form': function(e) {
e.preventDefault();
var post = {
url: $(e.target).find('[name=url]').val(),
title: $(e.target).find('[name=title]').val(),
message: $(e.target).find('[name=message]').val()
}
Meteor.call('post', post, function(error, id) {
if (error)
return alert(error.reason);
}
});
/ _
Meteor.call
A funo
submit js
),
formulrio
neste caso
o objeto
problema
chama um M
post
que n
Voc
pode
s do
todo do lado do
Aqui n
caso contrrio
s definimos o M
allow()
do
posts.js
j que o M
so executados no servidor
http://pt.discovermeteor.com/pdf
Lembre se que M
todos
122/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
return postId;
collections posts js
Commit76
Ver no GitHub
Este M
todo
um pouco complicado
http://pt.discovermeteor.com/pdf
Lanar Instncia
123/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Primeiro
existe
Ento
,
n
user
alert
eventualmente ser
jogando um erro
caso contrrio
o qual
s tamb
m fazemos
alguma validao simples do objeto artigo para garantir que os nossos artigos tenham t tulo
Em seguida
significa redirecionar
A classe
num
e o
Error
,
n
do Meteor recebe tr
s argumentos
302
O primeiro
( error )
o qual
vio
ser o c
digo
302 , o segundo reason uma pequena explicao legvel por humanos do erro,
rico
ltimo
( details )
,
No nosso caso
til adicional
acabamos de encontrar
Spoiler alert
existente
,
n
),
s queremos inserir
Finalmente
ao artigo
s inserimos o artigo
e retornamos a
id
OrganizandoArtigos
Agora que n
do Mongo
Para tanto
http://pt.discovermeteor.com/pdf
sort
e um sinal indicando se
124/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Template.postsList.helpers({
posts: function() {
return Posts.find({}, {sort: {submitted: -1}});
}
});
list js
Commit77
Ver no GitHub
mas n
Lanar Instncia
edit lo e delet lo
do tamb
http://pt.discovermeteor.com/pdf
125/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
CompensaodeLatncia
No
7.5
SIDEBAR
:
M
todos
Withoutlatencycompensation
Um M
todo Meteor
forma estruturada
No nosso exemplo
,
n
s usamos um M
todo porque n
certeza que os novos artigos estariam marcados com o nome do autor e id assim como o
Entretanto
problema
aleat
se o Meteor executasse M
+0
ms
ncia de eventos
(
):
note
s ter amos um
as timestamps so valores
es apenas ilustrativas
http://pt.discovermeteor.com/pdf
126/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
todo
+200
+500
ms
ms
tais a
es e ver os resultados
pr
).
las
CompensaodeLatncia
http://pt.discovermeteor.com/pdf
127/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Withlatencycompensation
Quando n
diret
rio
cliente
s definimos nosso M
todo
ncia
quanto no
Quando voc
http://pt.discovermeteor.com/pdf
todo
mas
128/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
tamb
m simultaneamente simula a ao do M
+0
+0
ms
ms
es do cliente
todo
es do cliente e muda a
las
ms
ms
UI refletiro isso
documentos can
).
trocando
As mundanas na
UI para reflet
+200
+500
que
veridicamente
ObservandoaCompensaodeLatncia
ao
Para tanto
s usaremos
isSimulation
paralelo
enquanto o M
real
adicionamos a string
http://pt.discovermeteor.com/pdf
(client)
uma simulao de M
s perguntamos ao Meteor se o c
adicionamos a string
Um stub
todo
futures
todo
Ento n
post
todo
Caso contrrio
Se sim
,
n
,
n
(server) :
129/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Meteor.methods({
post: function(postAttributes) {
// []
return postId;
collections posts js
Note
caso voc
esteja se perguntando
invocao de M
this
em
this.isSimulation um objeto de
teis
mas n
s basicamente
servidor
s tamb
http://pt.discovermeteor.com/pdf
130/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Template.postSubmit.events({
'submit form': function(event) {
event.preventDefault();
var post = {
url: $(event.target).find('[name=url]').val(),
title: $(event.target).find('[name=title]').val(),
message: $(event.target).find('[name=message]').val()
}
}
});
/ _
submit js
Commit751
Ver no GitHub
Se n
um artigo
o GitHub
):
inserido como
http://pt.discovermeteor.com/pdf
Lanar Instncia
,
n
(cliente)
em seu t tulo
ncia claramente
Primeiro
linkando para
131/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Ourpostasfirststoredintheclientcollection
Ento
ele
Ourpostoncetheclientreceivestheupdatefromtheservercollection
MtodonaColeodoCliente
http://pt.discovermeteor.com/pdf
132/261
1/8/2015
Voc
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
bem simples
s j vimos tr
insert , update
Quando voc
definindo tr
palavras
um M
1.
s M
os M
todos
quando voc
: posts/insert , posts/update
chama
Posts.insert()
posts/delete . Em outras
na coleo do cliente
todo de lat
remove .
s M
voc
est chamando
).
allow
deny
2.
MtodoschamandoMtodos
Se voc
est acompanhando
chamando outro M
todo
voc
( posts/insert )
quando n
todo
post
est
Como isso
funciona
Quando a simulao
simulao do
verso do M
insert
ento n
, insert
post
do lado do servidor
j que n
est rodando
),
chamamos o real
servidor do
s rodamos a
mas n
s no
far isso
Consequentemente
quando o M
todo
post
http://pt.discovermeteor.com/pdf
insert
no h
133/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
EditandoArtigos
Dado que o c
o pr
bastante simples
ximo passo
esta
es de utilizadores
Router.configure({
layoutTemplate: 'layout'
});
Router.map(function() {
this.route('postsList', {path: '/'});
this.route('postPage', {
path: '/posts/:_id',
data: function() { return Posts.findOne(this.params._id); }
});
this.route('postEdit', {
path: '/posts/:_id/edit',
data: function() { return Posts.findOne(this.params._id); }
});
this.route('postSubmit', {
path: '/submit'
});
});
var requireLogin = function() {
if (! Meteor.user()) {
if (Meteor.loggingIn())
this.render('loading')
else
this.render('accessDenied');
this.stop();
134/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
lib router js
OTemplateDeEdiodeArtigos
standard
O nosso template
postEdit
<template name="postEdit">
<form class="main">
<div class="control-group">
<label class="control-label" for="url">URL</label>
<div class="controls">
<input name="url" type="text" value="{{url}}" placeholder="Your
URL"/>
</div>
</div>
<div class="control-group">
<label class="control-label" for="title">Title</label>
<div class="controls">
<input name="title" type="text" value="{{title}}" placeholder="N
ame your post"/>
</div>
</div>
<div class="control-group">
<div class="controls">
<input type="submit" value="Submit" class="btn btn-primary submi
t"/>
</div>
</div>
<hr/>
<div class="control-group">
<div class="controls">
<a class="btn btn-danger delete" href="#">Delete post</a>
</div>
</div>
</form>
</template>
/ _
edit html
post_edit.js
http://pt.discovermeteor.com/pdf
135/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Template.postEdit.events({
'submit form': function(e) {
e.preventDefault();
var currentPostId = this._id;
var postProperties = {
url: $(e.target).find('[name=url]').val(),
title: $(e.target).find('[name=title]').val()
}
Posts.update(currentPostId, {$set: postProperties}, function(error) {
if (error) {
// display the error to the user
alert(error.reason);
} else {
Router.go('postPage', {_id: currentPostId});
}
});
},
'click .delete': function(e) {
e.preventDefault();
if (confirm("Delete this post?")) {
var currentPostId = this._id;
Posts.remove(currentPostId);
Router.go('postsList');
}
}
});
/ _
edit js
Primeiro
Depois
do formulrio
e outra para o
A callback do apagar
muito simples
do Template
submit
submeter
no link de apagar
apaga o artigo
http://pt.discovermeteor.com/pdf
click
e pedir ao
obt
.
136/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
A callback de edio
ligeiramente maior
).
Depois de
postProperties
propriedades do artigo
todo de Meteor
Collection.update() , e utilizamos
AdicionandoLinks
Devemos ainda adicionar links de edio aos nossos artigos para que os utilizadores tenham
<template name="postItem">
<div class="post">
<div class="post-content">
<h3><a href="{{url}}">{{title}}</a><span>{{domain}}</span></h3>
<p>
submitted by {{author}}
{{#if ownPost}}<a href="{{pathFor 'postEdit'}}">Edit</a>{{/if}}
</p>
</div>
<a href="{{pathFor 'postPage'}}" class="discuss btn">Discuss</a>
</div>
</template>
/ _
Naturalmente
item html
ownPost
http://pt.discovermeteor.com/pdf
entra
137/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Template.postItem.helpers({
ownPost: function() {
return this.userId == Meteor.userId();
},
domain: function() {
var a = document.createElement('a');
a.href = this.url;
return a.hostname;
}
});
/ _
item js
Formulriodeediodeartigo.
Commit81
Formulrio de edio de artigos adicionado
Ver no GitHub
Lanar Instncia
nada
O que
mas ainda no
que se passa
http://pt.discovermeteor.com/pdf
138/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
DefinindoPermisses
insecure , todas as modificaes feitas do
permissions.js
.
.
dentro de
carregada primeiro
es
Primeiro
):
lib permissions js
,
n
ignora o
s de um M
todos
allow()
todo de servidor
allow() .
posts.js
porque estvamos
vamos voltar ao
allow() :
collections posts js
http://pt.discovermeteor.com/pdf
139/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Commit82
Ver no GitHub
Lanar Instncia
LimitandoEdies
propriedade
Por exemplo
prios artigos
A callback
deny()
do Meteor
ser atualizados
collections posts js
Commit83
Permitir que apenas certos campos do artigo possam ser al
Ver no GitHub
http://pt.discovermeteor.com/pdf
Lanar Instncia
140/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
todo
without()
url
que no so
fieldNames
title .
ou
true
que cont
).
ou mais
0.
Se alguem est a
ChamadasaMtodosvsManipulaodeDadosNoLadodoCliente
apagar
estamos a utilizar o M
update
estamos a chamar
acesso usando
Quando
allow
todo
remove
deny .
allow
imediato
No entanto
).
Quando
isto
),
Chamadas a M
todo
todos tamb
.
:
preciso saber ou
s de uma callback
Para opera
http://pt.discovermeteor.com/pdf
es
por exemplo
contar
dias
).
somas
141/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
http://pt.discovermeteor.com/pdf
142/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
AllowandDeny
8.5
SIDEBAR
precisarmos definir M
Por n
s necessitarmos fazer tarefas auxiliares como decorar o post com propriedades extras e
usar um M
todo
post
posts
.
N
allow
,
es
e isto
deny .
Usar estas callbacks nos permite sermos mais declarativos quanto s modifica
de dados
sistema de contas
um b
es ao banco
nus adicional
Callbacksmltiplas
true
allow
),
no importa se
do c
e retornar um erro
403
insert
bem sucedido
deny insert
http://pt.discovermeteor.com/pdf
insert
deny . Se
Ento quando
para o cliente
callbacks retornar
,
n
Similarmente
quanto necessrias
ser retornado
sero executadas
A l
gica disto
allow insert
assim
143/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Note:n/estandsforNotExecuted
Em outras palavras
administrativos
qualquer post
Se o usurio atual
um administrador
CompensaodeLatncia
Lembre que M
compensada
atrav
todo
s do console
tais como
Por exemplo
voc
no
se voc
tentar deletar um
at
).
http://pt.discovermeteor.com/pdf
ncia
.update()
Entretanto
Por exemplo
voc
voc
no
precisa
precisa tomar
es de deletar para
144/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Felizmente
j que voc
por exemplo
e p
voc
pode compartilhar c
canDeletePost(user, post)
la no diret
extra
rio compartilhado
Permissesdoladodoservidor
iniciadas no cliente
No servidor
post
Ento voc
es do banco de dados
todo Meteor
deletePost
do lado do
do usurio dentro do M
es so permitidas
cheque as permiss
es
todo tamb
UsandoDenycomoumaCallback
Finalmente
Por exemplo
voc
deny us
lastModified
com o c
.
onX
digo seguinte
Posts.deny({
update: function(userId, doc, fields, modifier) {
doc.lastModified = +(new Date());
return false;
},
transform: null
});
Como callbacks
deny
update
bem sucedido
,
n
Admitidamente
usando um M
esta t
cnica
todo no lugar
ento voc
De qualquer forma
http://pt.discovermeteor.com/pdf
tipo um hack
ainda
beforeUpdate
bom saber
es
e no futuro n
s podemos
145/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
http://pt.discovermeteor.com/pdf
146/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Erros
alert()
Ao inv
um pouco insatisfat
rio
vamos construir um mecanismo de reportagem de erro mais verstil que far melhor
IntroduzindoColeesLocais
flash
do site
Este padro UX
til quando n
s queremos
O que n
s criaremos
mas
Para comear
muito mais s
til pois
,
n
apenas relevantes para a sesso atual e no precisam ser persistentes de forma alguma
apenas no navegador
Errors
existir
com o
que
http://pt.discovermeteor.com/pdf
147/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
deny
ou
.
N
throwError
que n
j que isto
allow
throwError = function(message) {
Errors.insert({message: message})
}
ela
reativa
forma que n
significando que n
que
es
Mostrandoerros
<template name="layout">
<div class="container">
{{> header}}
{{> errors}}
<div id="main" class="row-fluid">
{{yield}}
</div>
</div>
</template>
http://pt.discovermeteor.com/pdf
errors
error
em
errors.html :
148/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
<template name="errors">
<div class="errors row-fluid">
{{#each errors}}
{{> error}}
{{/each}}
</div>
</template>
<template name="error">
<div class="alert alert-error">
<button type="button" class="close" data-dismiss="alert">×</button
>
{{message}}
</div>
</template>
TemplatesGmeos
Voc
notar que n
se importa p
bem
um arquivo
Neste caso
main.html
um template
mas at
onde o Meteor
).
bem confuso
s faremos uma
agora
limpo
At
Template.errors.helpers({
errors: function() {
return Errors.find();
}
});
http://pt.discovermeteor.com/pdf
149/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Commit91
Basic error reporting
Ver no GitHub
Lanar Instncia
Criandoerros
Erros prov
mas n
ento n
,
do
e mostraremos uma
Em adio
existe
),
se n
s pegarmos o erro
302
artigo exitente do
error.details
terceiro argumento de
http://pt.discovermeteor.com/pdf
details
lembre se que n
da nossa classe
s obteremos o
s passamos o
Error
_id
no cap tulo
_id
do
do artigo como o
7.
150/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Template.postSubmit.events({
'submit form': function(e) {
e.preventDefault();
var post = {
url: $(e.target).find('[name=url]').val(),
title: $(e.target).find('[name=title]').val(),
message: $(e.target).find('[name=message]').val()
}
Meteor.call('post', post, function(error, id) {
if (error) {
// display the error to the user
throwError(error.reason);
}
});
/ _
submit js
Commit92
Actually use the error reporting
Ver no GitHub
Experimente
Lanar Instncia
http://pt.discovermeteor.com/pdf
voc
pode ver
151/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Triggeringanerror
LimpandoErros
Agora voc
pgina
Se voc
o fez
voc
gostaria
com o Meteor
error do DOM
<div>
do
melhor n
Primeiro
s modificaremos a funo
throwError
til mais tarde para sabermos se um error foi de fato visto pelo usurio
,
n
http://pt.discovermeteor.com/pdf
tamb
clearErrors
152/261
1/8/2015
erros
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
seen
Em seguida
// ...
Router.before(requireLogin, {only: 'postSubmit'})
Router.before(function() { clearErrors() });
lib router js
clearErrors()
funcionar
s precisamos resolver
),
instantaneamente
ser limpo
quando n
como n
s fazemos
o redirecionamento acontece
Isso significa que o usurio nunca tem a chance de ver o erro antes de este
para
seen .
true
seen
ser
.
til
modificada
http://pt.discovermeteor.com/pdf
s usaremos o
logo depois
Se ajudar
voc
pode
153/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
considerar que
continuar
O que n
s estamos fazendo
ap
s o template
errors
Isto
como
antes da callback
seen
para
true 1 milissegundo
s dissemos que o
exatamente o que n
s queremos
visto , o que significa que no ser limpo, o que significa que aparecer na pgina para
Template.errors.helpers({
errors: function() {
return Errors.find();
}
});
Template.error.rendered = function() {
var error = this.data;
Meteor.defer(function() {
Errors.update(error._id, {$set: {seen: true}});
});
};
Commit93
Ver no GitHub
rendered
O callback
navegador
Lanar Instncia
, this
Dentro do callback
this.data
nos permite acessar a informao do objeto que est atualmente sendo renderizado
caso
).
no nosso
um erro
http://pt.discovermeteor.com/pdf
154/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Whew
Isto
Ocallback rendered
rendered
O callback
Isto
claro
renderizado no navegador
mas
importante lembrar
re renderizado
es mudar
Ento voc
rastreamento de eventos
http://pt.discovermeteor.com/pdf
vulgo
primeiro quando
digo que no
ou c
neles
155/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
CriandoumPacoteMeteorite
9.5
SIDEBAR
envov
ento porque no
Primeiro n
symlinks no diret
rio
s pomos o
Voc
s de
packages/ .
Segundo
rio chamado
automaticamente utilizado
s criaremos
package.js
nessa pasta
Package.describe({
summary: "A pattern to display application errors to the user"
});
Package.on_use(function (api, where) {
api.use(['minimongo', 'mongo-livedata', 'templating'], 'client');
api.add_files(['errors.js', 'errors_list.html', 'errors_list.js'], 'client
');
if (api.export)
api.export('Errors');
});
Vamos adicionar tr
s arquivos ao pacote
sem muita mudana exceto por algum namespacing apropriado e uma API ligeiramente mais
limpa
http://pt.discovermeteor.com/pdf
156/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Errors = {
// Local (client-only) collection
collection: new Meteor.Collection(null),
};
throw: function(message) {
Errors.collection.insert({message: message, seen: false})
},
clearSeen: function() {
Errors.collection.remove({seen: true});
}
<template name="meteorErrors">
{{#each errors}}
{{> meteorError}}
{{/each}}
</template>
<template name="meteorError">
<div class="alert alert-error">
<button type="button" class="close" data-dismiss="alert">×</button
>
{{message}}
</div>
</template>
list html
Template.meteorErrors.helpers({
errors: function() {
return Errors.collection.find();
}
});
Template.meteorError.rendered = function() {
var error = this.data;
Meteor.defer(function() {
Errors.collection.update(error._id, {$set: {seen: true}});
});
};
http://pt.discovermeteor.com/pdf
157/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
list js
TestandoopacotecomMicroscope
Agora n
s rodamos
meteor add
$ rm client/helpers/errors.js
$ rm client/views/includes/errors.html
$ rm client/views/includes/errors.js
s precisamos fazer
correta
lib router js
{{> header}}
{{> meteorErrors}}
/ _
http://pt.discovermeteor.com/pdf
submit js
158/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
/ _
edit js
Commit951
Ver no GitHub
pr
Lanar Instncia
pacote de volta
Escrevendotestes
mas o pr
ximo
),
O Meteor em
Vamos criar um arquivo de teste que usa Tinytest para rodar alguns testes contra a nossa base
de c
http://pt.discovermeteor.com/pdf
159/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Nesses testes n
funcionando
tests js
est funcionando
digo
rendered
esto
no template ainda
Meteor.Errors
es bsicas de
),
mas felizmente
j que
funciona
http://pt.discovermeteor.com/pdf
160/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Package.on_test(function(api) {
api.use('errors', 'client');
api.use(['tinytest', 'test-helpers'], 'client');
api.add_files('errors_tests.js', 'client');
});
Commit952
Ver no GitHub
Ento n
Lanar Instncia
Terminal
http://pt.discovermeteor.com/pdf
161/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Passingalltests
Lanandoopacote
Agora
s fazemos isso
pondo o em Atmosphere
Primeiro
s precisamos adicionar um
"name": "errors",
"description": "A pattern to display application errors to the user",
"homepage": "https://github.com/tmeasday/meteor-errors",
"author": "Tom Coleman <tom@thesnail.org>",
"version": "0.1.0",
"git": "https://github.com/tmeasday/meteor-errors.git",
"packages": {
}
Commit953
Ver no GitHub
Lanar Instncia
s pomos alguma meta informao bsica para prover informao sobre o pacote
"pacotes"
e um n
lanar
ncias
s tamb
Se
m podemos utilizar o
fcil
http://pt.discovermeteor.com/pdf
s vamos hosped lo
segmento
incluindo
rio git
162/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
smart.json .
mrt release
comando
$ git
$ git
$ git
$ git
$ git
$ mrt
Done!
Terminal
Note
.
rio
,
rio
ento seguir a
Ento
,
n
s usamos o
para public lo
init
add -A
commit -m "Created Errors Package"
remote add origin https://github.com/tmeasday/meteor-errors.git
push origin master
release .
`)
packages errors
nicos
Voc
ento voc
No futuro a Atmosphere
//
- -
Outra coisa
Se voc
chamar
mrt release . .
$ rm -r packages/errors
$ mrt add errors
Terminal
http://pt.discovermeteor.com/pdf
163/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Commit954
Ver no GitHub
Agora n
Parab
Lanar Instncia
s devemos ver o Meteorite fazer download do nosso pacote pela primeira vez
ns
http://pt.discovermeteor.com/pdf
164/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Comentrios
10
la
e adicionando
collections comments js
// Fixture data
if (Posts.find().count() === 0) {
var now = new Date().getTime();
// create two users
var tomId = Meteor.users.insert({
profile: { name: 'Tom Coleman' }
});
var tom = Meteor.users.findOne(tomId);
var sachaId = Meteor.users.insert({
profile: { name: 'Sacha Greif' }
});
var sacha = Meteor.users.findOne(sachaId);
var telescopeId = Posts.insert({
title: 'Introducing Telescope',
userId: sacha._id,
author: sacha.profile.name,
url: 'http://sachagreif.com/introducing-telescope/',
submitted: now - 7 * 3600 * 1000
});
Comments.insert({
postId: telescopeId,
userId: tom._id,
author: tom.profile.name,
submitted: now - 5 * 3600 * 1000,
body: 'Interesting project Sacha, can I get involved?'
http://pt.discovermeteor.com/pdf
165/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
});
Comments.insert({
postId: telescopeId,
userId: sacha._id,
author: sacha.profile.name,
submitted: now - 3 * 3600 * 1000,
body: 'You sure can Tom!'
});
Posts.insert({
title: 'Meteor',
userId: tom._id,
author: tom.profile.name,
url: 'http://meteor.com',
submitted: now - 10 * 3600 * 1000
});
Posts.insert({
title: 'The Meteor Book',
userId: tom._id,
author: tom.profile.name,
url: 'http://themeteorbook.com',
submitted: now - 12 * 3600 * 1000
});
server fixtures js
Meteor.publish('posts', function() {
return Posts.find();
});
Meteor.publish('comments', function() {
return Comments.find();
});
server publications js
http://pt.discovermeteor.com/pdf
166/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Router.configure({
layoutTemplate: 'layout',
loadingTemplate: 'loading',
waitOn: function() {
return [Meteor.subscribe('posts'), Meteor.subscribe('comments')];
}
});
lib router js
Commit101
Ver no GitHub
o banco de dados
novo
s limpar
id
voc
precisar usar
),
completamente falsos
com
,
m
postId , e ao usurio
com
Tamb
para limpar
inserindo os no banco de
artigo
meteor reset
Primeiro
Lanar Instncia
digo de exemplos
Ap
Ento n
ligando o comentrio ao
junto com
artigos
Mostrandocomentrios
uma id
mas n
s tamb
m precisamos mostr
agora
e voc
tem
http://pt.discovermeteor.com/pdf
167/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
<template name="postPage">
{{> postItem}}
<ul class="comments">
{{#each comments}}
{{> comment}}
{{/each}}
</ul>
</template>
/ _
page html
Template.postPage.helpers({
comments: function() {
return Comments.find({postId: this._id});
}
});
/ _
s pomos o bloco
page js
{{#each comments}}
linear
s do atributo
this um
postId .
.
N
ento
Dado que n
rio
comments
renderizar um comentrio
dentro de
views
bem
<template name="comment">
<li>
<h4>
<span class="author">{{author}}</span>
<span class="date">on {{submittedText}}</span>
</h4>
<p>{{body}}</p>
</li>
</template>
http://pt.discovermeteor.com/pdf
168/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
submitted
?)
fluentemente
Template.comment.helpers({
submittedText: function() {
return new Date(this.submitted).toString();
}
});
Ento
s mostraremos o n
<template name="postItem">
<div class="post">
<div class="post-content">
<h3><a href="{{url}}">{{title}}</a><span>{{domain}}</span></h3>
<p>
submitted by {{author}},
<a href="{{pathFor 'postPage'}}">{{commentsCount}} comments</a>
{{#if ownPost}}<a href="{{pathFor 'postEdit'}}">Edit</a>{{/if}}
</p>
</div>
<a href="{{pathFor 'postPage'}}" class="discuss btn">Discuss</a>
</div>
</template>
/ _
item html
E adicionaremos o ajudante
http://pt.discovermeteor.com/pdf
commentsCount
ao nosso administrador
postItem :
169/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Template.postItem.helpers({
ownPost: function() {
return this.userId == Meteor.userId();
},
domain: function() {
var a = document.createElement('a');
a.href = this.url;
return a.hostname;
},
commentsCount: function() {
return Comments.find({postId: this._id}).count();
}
});
/ _
item js
Commit102
Display comments on
Ver no GitHub
`.
postPage
Lanar Instncia
s devemos ser capazes de mostrar nossos comentrios de exemplo e ver algo assim
http://pt.discovermeteor.com/pdf
170/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Displayingcomments
EnviandoComentrios
O processo que
<template name="postPage">
{{> postItem}}
<ul class="comments">
{{#each comments}}
{{> comment}}
{{/each}}
</ul>
{{#if currentUser}}
{{> commentSubmit}}
{{else}}
<p>Please log in to leave a comment.</p>
{{/if}}
</template>
/ _
page html
http://pt.discovermeteor.com/pdf
171/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
<template name="commentSubmit">
<form name="comment" class="comment-form">
<div class="control-group">
<div class="controls">
<label for="body">Comment on this post</label>
<textarea name="body"></textarea>
</div>
</div>
<div class="control-group">
<div class="controls">
<button type="submit" class="btn">Add Comment</button>
</div>
</div>
</form>
</template>
submit html
Thecommentsubmitform
commentSubmit
s chamamos um M
todo
comment
http://pt.discovermeteor.com/pdf
no administrador
postSubmit :
172/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Template.commentSubmit.events({
'submit form': function(e, template) {
e.preventDefault();
var $body = $(e.target).find('[name=body]');
var comment = {
body: $body.val(),
postId: template.data._id
};
}
});
submit js
Assim como n
configuraremos um M
leg timo
s previamente configuramos um M
todo Meteor
comment
todo
post
do lado do servidor
,
n
http://pt.discovermeteor.com/pdf
173/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
return Comments.insert(comment);
collections comments js
Commit103
Ver no GitHub
Lanar Instncia
que o
ControlandoaAssinaturadosComentrios
http://pt.discovermeteor.com/pdf
Isso
um desperd cio
J que
174/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Se n
particular
agora
s lemos toda
inicializado
Mas n
nosso c
At
Ento n
e esse
s precisaremos mover
ncia
ao inv
nosso aplicativo
que voc
s inicializamos
Isto significa
um ponto
para sempre
http://pt.discovermeteor.com/pdf
waitOn
175/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Router.map(function() {
//...
this.route('postPage', {
path: '/posts/:_id',
waitOn: function() {
return Meteor.subscribe('comments', this.params._id);
},
data: function() { return Posts.findOne(this.params._id); }
});
//...
});
lib router js
Voc
perceber que n
assinatura
s estamos passando
this.params._id
como um argumento
s restrinjamos nosso
Meteor.publish('posts', function() {
return Posts.find();
});
Meteor.publish('comments', function(postId) {
return Comments.find({postId: postId});
});
server publications js
Commit104
Ver no GitHub
H apenas um problema
http://pt.discovermeteor.com/pdf
quando n
Lanar Instncia
176/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
artigos tem
comentrios
Ourcommentsaregone!
ContandoComentrios
do artigo lido
ajudante
ento quando n
commentsCount
:
n
s chamamos
no administrador
Comments.find({postId: this._id})
no
voc
desnormalizar o n
!).
isso
Como veremos
a pr
se
de performance que n
digo
o benef cio
estrutura do
reset
post.
los
http://pt.discovermeteor.com/pdf
informao de
Para comear
para rel
commentsCount
):
meteor
177/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
server fixtures js
Ento
comentrio
collections posts js
E ento n
s atualizamos o
commentsCount
http://pt.discovermeteor.com/pdf
relevante quando n
$inc
s fazemos um novo
rico por um
):
178/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
collections comments js
Finalmente
commentsCount
do
nosso artigo
Commit105
Ver no GitHub
Lanar Instncia
notifica
E sabe mais
o pr
como implementar
http://pt.discovermeteor.com/pdf
179/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Desnormalizao
10.5
SIDEBAR
palavras
ltiplas c
normal
Em outras
No
s desnormalizamos a contagem do n
informao isto
redundante
j que n
).
es
quanto performance
exemplo
No nosso
s tamb
precisamos nos lembrar de atualizar o artigo relevante para assegurar que o campo
commentsCount
continue correto
Isto
exatamente o porqu
Entretanto
UmaPublicaoEspecial
Seria poss vel criar uma publicao especial que enviaria apenas a contagem de
comentrios que n
artigos que n
Mas
s estamos interessados
s atualmente vemos
atrav
).
http://pt.discovermeteor.com/pdf
180/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Claro
tais considera
na informao
se voc
de suma importncia
est escrevendo um
ncias
do que
ganhos de performance
EmbutindoDocumentosouCriandoColeesMltiplas
Se voc
experiente em Mongo
voc
s criamos uma
A questo
que vrias das ferramentas que o Meteor d funcionam bem melhor quando se
1.
O ajudante
de
Por exemplo
o resultado
2. allow
deny
qualquer modifica
3.
comments
no artigo
isto significa se
4.
Publica
Por exemplo
se n
pria coleo
pegar documentos
Entretanto
arquitetura do Meteor
cliente
isto no
http://pt.discovermeteor.com/pdf
essencialmente livre
181/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
AsDesvantagensdaDesnormalizao
H um bom argumento a ser feito sobre porque no devemos desnormalizar nossa
informao
recomendamos Why You Should Never Use MongoDB por Sarah Mei
http://pt.discovermeteor.com/pdf
182/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Notificaes
11
Agora que os usurios possam comentar nos artigos uns dos outros
los
Para tanto
Este
padro
es instantaneamente
s no precisamos esperar o
novas notifica
digo especial
Criandonotificaes
notifica
No futuro
createCommentNotification
http://pt.discovermeteor.com/pdf
183/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
collections notifications js
que n
s tamb
s restrinjamos as permiss
Notifications
J que n
m disponibilizamos atualiza
,
es
es uma vez
es de atualizao pr
s tamb
m criamos uma simples funo que olha para o artigo que o usurio est
comentando
esta coleo
_id
Comments.insert(comment);
por
do rec
ento n
s trocaremos
return
comment._id = Comments.insert(comment)
s podemos
para salvar a
createCommentNotification :
http://pt.discovermeteor.com/pdf
184/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
// [...]
// create the comment, save the id
comment._id = Comments.insert(comment);
// now create a notification, informing the user that there's been a com
ment
createCommentNotification(comment);
return comment._id;
}
});
collections comments js
Vamos tamb
m publicar as notifica
es
// [...]
Meteor.publish('notifications', function() {
return Notifications.find();
});
server publications js
Router.configure({
layoutTemplate: 'layout',
loadingTemplate: 'loading',
waitOn: function() {
return [Meteor.subscribe('posts'), Meteor.subscribe('notifications')]
}
});
lib router js
http://pt.discovermeteor.com/pdf
185/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Commit111
Ver no GitHub
Lanar Instncia
MostrandoNotificaes
Agora n
es ao cabealho
<template name="header">
<header class="navbar">
<div class="navbar-inner">
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-col
lapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<a class="brand" href="{{pathFor 'postsList'}}">Microscope</a>
<div class="nav-collapse collapse">
<ul class="nav">
{{#if currentUser}}
<li>
<a href="{{pathFor 'postSubmit'}}">Submit Post</a>
</li>
<li class="dropdown">
{{> notifications}}
</li>
{{/if}}
</ul>
<ul class="nav pull-right">
<li>{{loginButtons}}</li>
</ul>
</div>
</div>
</header>
</template>
E criar os templates
notifications
http://pt.discovermeteor.com/pdf
notification
186/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
arquivo
notifications.html :
<template name="notifications">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
Notifications
{{#if notificationCount}}
<span class="badge badge-inverse">{{notificationCount}}</span>
{{/if}}
<b class="caret"></b>
</a>
<ul class="notification dropdown-menu">
{{#if notificationCount}}
{{#each notifications}}
{{> notification}}
{{/each}}
{{else}}
<li><span>No Notifications</span></li>
{{/if}}
</ul>
</template>
<template name="notification">
<li>
<a href="{{notificationPostPath}}">
<strong>{{commenterName}}</strong> commented on your post
</a>
</li>
</template>
comentado
Em seguida
nosso administrador
e atualizamos as notifica
es como
lidas
es no
http://pt.discovermeteor.com/pdf
187/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Template.notifications.helpers({
notifications: function() {
return Notifications.find({userId: Meteor.userId(), read: false});
},
notificationCount: function(){
return Notifications.find({userId: Meteor.userId(), read: false}).count(
);
}
});
Template.notification.helpers({
notificationPostPath: function() {
return Router.routes.postPage.path({_id: this.postId});
}
})
Template.notification.events({
'click a': function() {
Notifications.update(this._id, {$set: {read: true}});
}
})
Commit112
Ver no GitHub
Voc
estrutura deles
bem similar
que n
Lanar Instncia
es no so to diferentes de erros
,
e
verdade que a
es so persistentes e
desde
es do
Tente
).
Chrome
Voc
),
digamos o Firefox
http://pt.discovermeteor.com/pdf
a qual voc
deixou aberta no
188/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Displayingnotifications.
Controlandoacessosnotificaes
As notifica
notifica
Se voc
es so p
nossas
blicas
tente rodar o c
do navegador
Notifications.find().count();
Browser console
Notifications
As notifica
es
original
http://pt.discovermeteor.com/pdf
es de privacidade em potencial
189/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
todas notifica
grande o suficiente
a causar s
Num site
es
es para
navegador
.
,
na nossa publicao
Notifications.find()
.
N
es do
usurio logado
Fazer isso
em
bem linear
publish
_id
do usurio logado
this.userId :
Meteor.publish('notifications', function() {
return Notifications.find({userId: this.userId});
});
server publications js
Commit113
Ver no GitHub
Agora se n
cole
Lanar Instncia
es de notifica
es diferentes
Notifications.find().count();
http://pt.discovermeteor.com/pdf
190/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Browser console
user
Notifications.find().count();
Browser console
Na verdade
aplicativo
user
a lista de Notifica
Isto
usurio muda
es deve at
porque publica
http://pt.discovermeteor.com/pdf
s checaremos isso no pr
191/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
ReatividadeAvanada
raro voc
til entend
gostaram
ncias
mas
certamente
informao relevante
Imagine que n
11.5
SIDEBAR
.
N
s j resolvemos os detalhes de
e anlise da
s agora temos uma funo ass ncrona do lado do cliente que retorna
o n
mero de likes
tempo real
que ela
bastante no reativa e no em
e a far
mudar
setInterval
currentLikeCount = 0;
Meteor.setInterval(function() {
var postId;
if (Meteor.user() && postId = Session.get('currentPostId')) {
getFacebookLikeCount(Meteor.user(), Posts.find(postId),
function(err, count) {
if (!err)
currentLikeCount = count;
});
}
}, 5 * 1000);
s checarmos a varivel
o n
segundos
http://pt.discovermeteor.com/pdf
192/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Template.postItem.likeCount = function() {
return currentLikeCount;
}
Entretanto
mudar
currentLikeCount
Apesar da varivel ser agora pseudo em tempo real j que ela muda sozinha
ela no
reativa ento ela ainda no consegue se comunicar devidamente com o resto do ecosistema
do Meteor
RastreandoReatividade:Computaes
A reatividade do Meteor
ncias
um conjunto de computa
es
Como n
do c
No nosso caso
uma computao
um segmento
Voc
informao reativa
via
digo que
se importa
quanto
TransformandoumaVarivelemumaFunoReativa
currentLikeCount
http://pt.discovermeteor.com/pdf
):
ncia
,
n
Isto requer
193/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
var _currentLikeCount = 0;
var _currentLikeCountListeners = new Deps.Dependency();
currentLikeCount = function() {
_currentLikeCountListeners.depend();
return _currentLikeCount;
}
Meteor.setInterval(function() {
var postId;
if (Meteor.user() && postId = Session.get('currentPostId')) {
getFacebookLikeCount(Meteor.user(), Posts.find(postId),
function(err, count) {
if (!err && count !== _currentLikeCount) {
_currentLikeCount = count;
_currentLikeCountListeners.changed();
}
});
}
}, 5 * 1000);
O que n
muda
Essas computa
ncia
_currentLikeCount
valor de
_currentLikeCountListerners , a qual
currentLinkCount()
s chamamos a funo
es rastreadas
foi utilizada
changed()
Quando o
nesta depend
ncia
.
.
Neste
ComputaodeTemplateeControlandooRedesenhar
pria computao
Quando n
interior muda
intacto
Desta forma
redesenhado por
computa
reativas
http://pt.discovermeteor.com/pdf
194/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
O Meteor tamb
aninhar templates
Primeiro
{{#constant}}
o ajudante em bloco
Ento
deixado de
es constantes uma
grande forma de adminsitrar widgets de terceiros que no esto esperando que o Meteor re
palavras
o ajudante em bloco
Em outras
Ento se uma das fontes de informao reativa dentro do bloco isolate mudar
ser re desenhada
re desenhar por
a rea isolada
Se o template superior
.
m
ComparandoDepsaAngular
Angular
Meteor e do Angular
computa
reativas
fun
es
Essas
que tratam de
.
es
http://pt.discovermeteor.com/pdf
es
Adicionalmente
es
ncias do
voc
suas depend
desenvolvida
quiser
195/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Em Angular
a reatividade
Quando voc
todos especiais
.
,
escopo voc
Ento voc
se importa
voc
chama
e uma funo ouvinte que rodar cada vez que a expresso mudar
,
n
s escrever amos
$rootScope.$watch('currentLikeCount', function(likeCount) {
console.log('Current like count is ' + likeCount);
});
Claro
$watch
{{expressions}}
no chama
ng-model
, scope.$apply()
Isto re avalia
escopo
voc
Ento
es em Meteor
ao inv
re avaliados
s de lhe dar o controle quanto a dizer precisamente quais ouvintes devem ser
inteligente e eficiente na forma como ele determina precisamente quais ouvintes precisam ser
re avaliados
.
,
Com Angular
nosso c
http://pt.discovermeteor.com/pdf
digo da funo
getFacebookLikeCount()
196/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Meteor.setInterval(function() {
getFacebookLikeCount(Meteor.user(), Posts.find(postId),
function(err, count) {
if (!err) {
$rootScope.currentLikeCount = count;
$rootScope.$apply();
}
});
}, 5 * 1000);
Admitidamente
es se mostrar
s e nos deixa
Mas felizmente
adiante
http://pt.discovermeteor.com/pdf
197/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Paginao
12
Assim provavelmente
es de performance do
mero de artigos novos que vo ser criados no site quando este for lanado
Anteriormente falmos de como uma coleo no lado do cliente deve conter um sub conjunto
e at
es de notifica
es
e comentrios
No entanto
utilizadores ligados
problemtico
Eventualmente
para todos os
isto ser
AdicionandoMaisArtigos
Primeiro
http://pt.discovermeteor.com/pdf
198/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
// Fixture data
if (Posts.find().count() === 0) {
//...
Posts.insert({
title: 'The Meteor Book',
userId: tom._id,
author: tom.profile.name,
url: 'http://themeteorbook.com',
submitted: now - 12 * 3600 * 1000,
commentsCount: 0
});
server fixtures js
Depois de executar
http://pt.discovermeteor.com/pdf
199/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Mostrandodadosdeteste.
Commit121
Ver no GitHub
Lanar Instncia
PaginaoInfinita
fundo
, 10
por exemplo
infinito
10
artigos no ecr
artigos lista
com um link
carregar mais
representa o n
no
Isto
Agora vamos precisar de uma forma de comunicar este parmetro ao servidor para que ele
publicao
posts
no roteador
m o
http://pt.discovermeteor.com/pdf
200/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
parte do caminho
http://localhost:3000/25 . Um bons
mostrar
ver
25
25
todos
vamos continuar a
artigos
nosso c
Primeiro
Basta remover
posts
no bloco
digo
Router.configure() .
notifications :
Router.configure({
layoutTemplate: 'layout',
loadingTemplate: 'loading',
waitOn: function() {
return [Meteor.subscribe('notifications')]
}
});
lib router js
postsLimit
combinar com
ao caminho da rota
opcional
Ou seja
Adicionar um
a nossa rota no s
vai
http://localhost:3000 .
http://pt.discovermeteor.com/pdf
201/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Router.map(function() {
//...
this.route('postsList', {
path: '/:postsLimit?'
});
});
lib router js
/:parameter?
Dado que cada rota vai ser analisada sucessivamente para ver se combina
especificidade decrescente
Noutras palavras
vir primeiro
e a nossa rota
postsList
/posts/:_id
devem
Est agora na altura de lidar com o problema dif cil de subscrever e encontrar os dados
corretos
Vamos usar
postsLimit
no est presente
Router.map(function() {
//..
this.route('postsList', {
path: '/:postsLimit?',
waitOn: function() {
var postsLimit = parseInt(this.params.postsLimit) || 5;
return Meteor.subscribe('posts', {sort: {submitted: -1}, limit: postsL
imit});
}
});
});
lib router js
http://pt.discovermeteor.com/pdf
202/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
options
para o c
posts
digo de servidor
).
artigos
({
limit
postsLimit
})
em conjunto
Meteor.publish('posts', function(options) {
return Posts.find({}, options);
});
Meteor.publish('comments', function(postId) {
return Comments.find({postId: postId});
});
Meteor.publish('notifications', function() {
return Notifications.find({userId: this.userId});
});
server publications js
http://pt.discovermeteor.com/pdf
203/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
PassandoParmetros
O nosso c
postsLimit}
options
da operao de
, {limit:
no nosso caso
poss vel que utilizadores possam submeter qualquer opo que queiram atrav
s da
consola do navegador
No nosso caso
fazer
isto
relativamente segura
).
ou mudar o limite
que
o que
No entanto esta abordagem no deve ser usada quando se esto a guardar dados
opo
fields
argumento do selector do
e tamb
find()
es de segurana
Uma abordagem mais segura poderia ser passar os parmetros individuais em vez do
objecto todo
funo
data
tamb
dentro do template
posts .
http://pt.discovermeteor.com/pdf
o c
this
204/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Router.map(function() {
this.route('postsList', {
path: '/:postsLimit?',
waitOn: function() {
var limit = parseInt(this.params.postsLimit) || 5;
return Meteor.subscribe('posts', {sort: {submitted: -1}, limit: limit}
);
},
data: function() {
var limit = parseInt(this.params.postsLimit) || 5;
return {
posts: Posts.find({}, {sort: {submitted: -1}, limit: limit})
};
}
});
//..
});
lib router js
Agora que estamos a definir o contexto de dados ao nivel do roteador podemos com
posts
dentro do ficheiro
),
do ajudante
Vamos recapitular
postsList
digo do
router.js
o mesmo nome
parecer
http://pt.discovermeteor.com/pdf
205/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Router.configure({
layoutTemplate: 'layout',
loadingTemplate: 'loading',
waitOn: function() {
return [Meteor.subscribe('notifications')]
}
});
Router.map(function() {
//...
);
this.route('postsList', {
path: '/:postsLimit?',
waitOn: function() {
var limit = parseInt(this.params.postsLimit) || 5;
return Meteor.subscribe('posts', {sort: {submitted: -1}, limit: limit}
},
data: function() {
var limit = parseInt(this.params.postsLimit) || 5;
return {
posts: Posts.find({}, {sort: {submitted: -1}, limit: limit})
};
}
});
});
lib router js
Commit122
Ver no GitHub
Lanar Instncia
mostrar um n
parmetro de URL
Por exemplo
experimente aceder a
http://pt.discovermeteor.com/pdf
206/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Controlandoonmerodeartigosnapginainicial.
http://pt.discovermeteor.com/pdf
207/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Porquenopginas?
Porque
resultados de pesquisas
Isto
10
artigos cada
paginao infinita
em vez de
Posts
mostra os artigos
10
10 20.
a
usando o formato
2,
que
artigos anteriores
O artigo
10
de tempo real
9,
e desapareceria de vista
.
11
coleo
paginao tradicional
s publicamos os artigos
10 20
selecionar os artigos
10 20,
.
at
cnicos
10
at
da
No se pode
artigos no total no
depois fazer um
Posts.find()
40.
Temos agora
20
,
.
es
10 20,
at
at
artigos no servidor
10
30
http://pt.discovermeteor.com/pdf
208/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
CriandoumControladordeRota
var limit =
parseInt(this.params.postsLimit) || 5;
coded no
exatamente ideal
Isto no
duas vezes
ter o n
prio
Controladores de Rota
mero
sempre melhor
hard
Um controlador de
simplesmente uma forma de agrupar caracter sticas de roteamento juntas num pacote
m disso
No se repita a si pr
rota
Al
o fim do munda
nica rota
.
til
PostsListController = RouteController.extend({
template: 'postsList',
increment: 5,
limit: function() {
return parseInt(this.params.postsLimit) || this.increment;
},
findOptions: function() {
return {sort: {submitted: -1}, limit: this.limit()};
},
waitOn: function() {
return Meteor.subscribe('posts', this.findOptions());
},
data: function() {
return {posts: Posts.find({}, this.findOptions())};
}
});
Router.map(function() {
//...
this.route('postsList', {
path: '/:postsLimit?',
controller: PostsListController
});
});
lib router js
http://pt.discovermeteor.com/pdf
209/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Primeiro
limit
extra
.
es
e uma funo
waitOn
es de
data
de
findOptions .
Uma
A seguir
increment .
findOptions
dizer rota
postsList
com
controller .
a propriedade
Commit123
Ver no GitHub
Lanar Instncia
AdicionandoumLinkdeCarregarMais
e o nosso c
Existe s
um problema
no
existe nenhuma forma de de facto usar essa paginao excepto alterando o URL
manualmente
Isto definitivamente no
ncia de utilizao
portanto vamos
bastante simples
por
clicado
Ou seja
http://localhost:3000/5 , clicar
carregar mais
no
carregar mais
http://localhost:3000/10 . Se chegou a este ponto no livro, confiamos que pode lidar com
alguma aritm
tica
http://pt.discovermeteor.com/pdf
210/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Como dantes
Lembra se quando
cursor anonimo
passar cursores
Bem
data
pode apenas
carregar mais
PostsListController = RouteController.extend({
template: 'postsList',
increment: 5,
limit: function() {
return parseInt(this.params.postsLimit) || this.increment;
},
findOptions: function() {
return {sort: {submitted: -1}, limit: this.limit()};
},
waitOn: function() {
return Meteor.subscribe('posts', this.findOptions());
},
posts: function() {
return Posts.find({}, this.findOptions());
},
data: function() {
var hasMore = this.posts().count() === this.limit();
var nextPath = this.route.path({postsLimit: this.limit() + this.incremen
t});
return {
posts: this.posts(),
nextPath: hasMore ? nextPath : null
};
}
});
lib router js
postsList
atualmente a trabalhar
Assim quando n
PostsListController
recebe um parmetro
s passamos
no qual estamos
postsLimit .
http://pt.discovermeteor.com/pdf
ao
prio caminho
.
211/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Noutras palavras
'postsList'}}
isto
{{pathFor
do Handlebars
this
s estamos a usar esse caminho e a adicion lo ao contexto de dados para o nosso template
complicada
s sabemos que
mostrar
cont
this.limit()
devolve o n
algo
(5)
se o URL no
m nenhum parmetro
, this.posts
se ao n
por isso
this.posts.count()
refere
que
carregar mais
artigos e recebemos
de volta
vamos
e recebemos menos
n , ento isto significa que atingimos o limite e que temos de parar de mostrar esse
boto
dados
exatamente
Infelizmente
quando o n
carregar mais
artigos e receber
artigos de
- -
garantindo que s
adicionar o link de
carregar mais
http://pt.discovermeteor.com/pdf
212/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
<template name="postsList">
<div class="posts">
{{#each posts}}
{{> postItem}}
{{/each}}
{{#if nextPath}}
<a class="load-more" href="{{nextPath}}">Load more</a>
{{/if}}
</div>
</template>
Isto
list html
Obotodecarregarmais.
()
nextPath
Commit124
foi adicionado ao controlador e
Ver no GitHub
http://pt.discovermeteor.com/pdf
agora usado
Lanar Instncia
213/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
UmaMelhorBarradeProgresso
loading
template de
carregar mais
voltamos ao
O resultado
que
de cada vez somos enviados de novo para o topo da pgina e precisamos de fazer scroll at
ao
Seria muito
ao mesmo tempo providenciar algum tipo de indicao de que novos dados esto a ser
carregados
Felizmente
isto
progress
iron-router-progress
faz
, iron-router-
Implementar isto
to
consola bash
Atrav
perfeitamente ap
s instalar
postSubmit
de contas
Vamos desligar
iron-router-progress
para a rota
http://pt.discovermeteor.com/pdf
):
no final
214/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Router.map(function() {
//...
this.route('postSubmit', {
path: '/submit',
disableProgress: true
});
});
lib router js
Commit125
Ver no GitHub
Lanar Instncia
AcedendoQualquerArtigo
algu
http://pt.discovermeteor.com/pdf
215/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Umtemplatevazio
Se tentar
subscrever publicao
agora
ao carregar a rota
consigo
poss vel ter mais que uma publicao para cada coleo
publicao nova
pelo
postPage .
Mas at
posts
separada
chamada
singlePost
identificado
_id .
Meteor.publish('posts', function(options) {
return Posts.find({}, options);
});
Meteor.publish('singlePost', function(id) {
return id && Posts.find(id);
});
server publications js
Agora
publicao
comments
na funo
adicionar a subscrio a
http://pt.discovermeteor.com/pdf
waitOn
singlePost
ai
da rota
J estamos a subscrever
m adicionar a
216/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Router.map(function() {
//...
this.route('postPage', {
path: '/posts/:_id',
waitOn: function() {
return [
Meteor.subscribe('singlePost', this.params._id),
Meteor.subscribe('comments', this.params._id)
];
},
data: function() { return Posts.findOne(this.params._id); }
});
this.route('postEdit', {
path: '/posts/:_id/edit',
waitOn: function() {
return Meteor.subscribe('singlePost', this.params._id);
},
data: function() { return Posts.findOne(this.params._id); }
});
/...
});
lib router js
Commit126
Usar uma subscrio a um
Ver no GitHub
escalabilidade
Lanar Instncia
pico do pr
seria ento bom ter uma forma qualquer de classificar esses links
http://pt.discovermeteor.com/pdf
Votao
Isto
No
precisamente o
217/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Votao
13
complicado
O que n
s precisamos
artigos
em Telescope
).
decaimento de
,
n
receberam
Vamos comear por dar aos usurios uma forma de votar nos artigos
ModelodeInformao
http://pt.discovermeteor.com/pdf
218/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
PrivacidadedaInformao&Publicaes
N
o que
tamb
atrav
s do console do navegador
Este
como as cole
es funcionam
Por exemplo
ncia
mas
Tamb
m note que se n
s quis
publicao
es
fields
,
n
da nossa
ou ao no
s tamb
m desnormalizaremos o n
recepo dele
Ento n
, upvoters
// Fixture data
if (Posts.find().count() === 0) {
var now = new Date().getTime();
// create two users
var tomId = Meteor.users.insert({
profile: { name: 'Tom Coleman' }
});
var tom = Meteor.users.findOne(tomId);
var sachaId = Meteor.users.insert({
profile: { name: 'Sacha Greif' }
});
var sacha = Meteor.users.findOne(sachaId);
var telescopeId = Posts.insert({
title: 'Introducing Telescope',
userId: sacha._id,
author: sacha.profile.name,
url: 'http://sachagreif.com/introducing-telescope/',
http://pt.discovermeteor.com/pdf
219/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
220/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
server fixtures js
Como de costume
rode
//...
// check that there are no previous posts with the same link
if (postAttributes.url && postWithSameLink) {
throw new Meteor.Error(302,
'This link has already been posted',
postWithSameLink._id);
}
// pick out the whitelisted keys
var post = _.extend(_.pick(postAttributes, 'url', 'title', 'message'), {
userId: user._id,
author: user.username,
submitted: new Date().getTime(),
commentsCount: 0,
upvoters: [],
votes: 0
});
var postId = Posts.insert(post);
return postId;
//...
collections posts js
ConstruindonossosTemplatesdeVotao
Primeiro
http://pt.discovermeteor.com/pdf
221/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
<template name="postItem">
<div class="post">
<a href="#" class="upvote btn"></a>
<div class="post-content">
<h3><a href="{{url}}">{{title}}</a><span>{{domain}}</span></h3>
<p>
{{votes}} Votes,
submitted by {{author}},
<a href="{{pathFor 'postPage'}}">{{commentsCount}} comments</a>
{{#if ownPost}}<a href="{{pathFor 'postEdit'}}">Edit</a>{{/if}}
</p>
</div>
<a href="{{pathFor 'postPage'}}" class="discuss btn">Discuss</a>
</div>
</template>
/ _
item html
Theupvotebutton
Em seguida
s chamaremos um M
boto
http://pt.discovermeteor.com/pdf
222/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
//...
Template.postItem.events({
'click .upvote': function(e) {
e.preventDefault();
Meteor.call('upvote', this._id);
}
});
/ _
Finalmente
item js
collections/posts.js
e adicionaremos o
Meteor.methods({
post: function(postAttributes) {
//...
},
upvote: function(postId) {
var user = Meteor.user();
// ensure the user is logged in
if (!user)
throw new Meteor.Error(401, "You need to login to upvote");
var post = Posts.findOne(postId);
if (!post)
throw new Meteor.Error(422, 'Post not found');
if (_.include(post.upvoters, user._id))
throw new Meteor.Error(422, 'Already upvoted this post');
}
});
Posts.update(post._id, {
$addToSet: {upvoters: user._id},
$inc: {votes: 1}
});
collections posts js
http://pt.discovermeteor.com/pdf
223/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Commit131
Ver no GitHub
Este M
todo
bem linear
Lanar Instncia
Ento n
s checamos se o usurio j no
s incrementamos o n
interessante
j que n
um campo de inteiro
: $addToSet
teis
$inc
adiciona um
simplesmente incrementa
TruquesnaInterfacedoUsurio
classe CSS
disabled
Para
ao boto upvote
<template name="postItem">
<div class="post">
<a href="#" class="upvote btn {{upvotedClass}}"></a>
<div class="post-content">
//...
</div>
</template>
/ _
http://pt.discovermeteor.com/pdf
item html
224/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Template.postItem.helpers({
ownPost: function() {
//...
},
domain: function() {
//...
},
upvotedClass: function() {
var userId = Meteor.userId();
if (userId && !_.include(this.upvoters, userId)) {
return 'btn-primary upvotable';
} else {
return 'disabled';
}
}
});
Template.postItem.events({
'click .upvotable': function(e) {
e.preventDefault();
Meteor.call('upvote', this._id);
}
});
/ _
item js
.upvote
para
http://pt.discovermeteor.com/pdf
225/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Greyingoutupvotebuttons.
Commit132
Grey out upvote link when not logged in
Ver no GitHub
Em seguida
voc
already voted
rico que n
votos
ento
Handlebars gen
Lanar Instncia
s faremos um ajudante
http://pt.discovermeteor.com/pdf
226/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Os ajudantes que n
eles se aplicavam
Mas ao utilizar
<template name="postItem">
//...
<p>
{{pluralize votes "Vote"}},
submitted by {{author}},
<a href="{{pathFor 'postPage'}}">{{pluralize commentsCount "comment"}}</a>
{{#if ownPost}}<a href="{{pathFor 'postEdit'}}">Edit</a>{{/if}}
</p>
//...
</template>
/ _
item html
PerfectingProperPluralization(nowsaythat10times)
http://pt.discovermeteor.com/pdf
227/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Commit133
Added pluralize helper to format text better
Ver no GitHub
vote
Lanar Instncia
AlgoritmodeVotaomaisinteligente
Nosso c
todo upvote
,
n
para atualiz lo
es pertinentes a isso
2.
3.
Primeiramente
Por
1.
No
ento outra
H duas quest
mas n
:
.
Caso contrrio
1 3
e
http://pt.discovermeteor.com/pdf
13
Nosso c
Felizmente
228/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Meteor.methods({
post: function(postAttributes) {
//...
},
upvote: function(postId) {
var user = Meteor.user();
// ensure the user is logged in
if (!user)
throw new Meteor.Error(401, "You need to login to upvote");
}
});
Posts.update({
_id: postId,
upvoters: {$ne: user._id}
}, {
$addToSet: {upvoters: user._id},
$inc: {votes: 1}
});
collections posts js
Commit134
Ver no GitHub
O que n
s estamos dizendo
ainda no votou
nica desvantagem
j votou
que agora n
j que n
id
Lanar Instncia
ento a consulta no
).
http://pt.discovermeteor.com/pdf
upvote
229/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
CompensaodeLatncia
Vamos dizer que voc
modificando o n
mero de votos
onde
Esta tentativa descarada de burlar o sistema seria pega pela nossa callback
em
?)
collections/posts.js , lembra
Mas se voc
olhar cuidadosamente
lat
ncia em ao
voc
deny()
e imediatamente negada
O que aconteceu
incidente
Na nossa coleo
Posts
Enquanto isso
no servidor
update
retornou um error
O resultado final
local
update
foi negado
),
o servidor
negar a modificao
a interface do usurio
RanqueandoosArtigosdaPginaPrincipal
Agora que n
Para tanto
,
n
mero de votos
vamos
postsList
um
Para comear
,
n
http://pt.discovermeteor.com/pdf
O truque aqui
230/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
argumentos diferentes
s tamb
URLs
/new
).
/best
respecitvamente
junto com
newPosts
/new/5
/best/5
claro
distintos
NewPostsListController
PostsListController
nico
NewPostsListController
ao nos dar um
em dois controladores
home
do qual herdar
newPosts ,
E adicionalmente
apenas
uma boa ilustrao de quo flex vel o Iron Router pode ser
PostsListController = RouteController.extend({
template: 'postsList',
increment: 5,
limit: function() {
return parseInt(this.params.postsLimit) || this.increment;
},
findOptions: function() {
return {sort: this.sort, limit: this.limit()};
},
waitOn: function() {
return Meteor.subscribe('posts', this.findOptions());
},
posts: function() {
return Posts.find({}, this.findOptions());
},
data: function() {
var hasMore = this.posts().fetch().length === this.limit();
return {
posts: this.posts(),
nextPath: hasMore ? this.nextPath() : null
};
}
});
NewPostsListController = PostsListController.extend({
sort: {submitted: -1, _id: -1},
nextPath: function() {
return Router.routes.newPosts.path({postsLimit: this.limit() + this.incr
ement})
}
});
http://pt.discovermeteor.com/pdf
231/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
BestPostsListController = PostsListController.extend({
sort: {votes: -1, submitted: -1, _id: -1},
nextPath: function() {
return Router.routes.bestPosts.path({postsLimit: this.limit() + this.inc
rement})
}
});
Router.map(function() {
this.route('home', {
path: '/',
controller: NewPostsListController
});
this.route('newPosts', {
path: '/new/:postsLimit?',
controller: NewPostsListController
});
this.route('bestPosts', {
path: '/best/:postsLimit?',
controller: BestPostsListController
});
// ..
});
lib router js
PostsListController
e para dentro de
s tiramos a l
gica
NewPostsListController
nextPath
para fora do
Adicionalmente
quando n
s organizamos por
secundria por timestamp submetida para assegurar que a ordem est correta
s tamb
http://pt.discovermeteor.com/pdf
232/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
<template name="header">
<header class="navbar">
<div class="navbar-inner">
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-col
lapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<a class="brand" href="{{pathFor 'home'}}">Microscope</a>
<div class="nav-collapse collapse">
<ul class="nav">
<li>
<a href="{{pathFor 'newPosts'}}">New</a>
</li>
<li>
<a href="{{pathFor 'bestPosts'}}">Best</a>
</li>
{{#if currentUser}}
<li>
<a href="{{pathFor 'postSubmit'}}">Submit Post</a>
</li>
<li class="dropdown">
{{> notifications}}
</li>
{{/if}}
</ul>
<ul class="nav pull-right">
<li>{{loginButtons}}</li>
</ul>
</div>
</div>
</header>
</template>
http://pt.discovermeteor.com/pdf
233/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Rankingbypoints
Commit135
Ver no GitHub
Lanar Instncia
UmCabealhoMelhor
Agora que n
atualmente
header.js
administrador
A razo para n
s querermos suportar m
newPosts
mesmo template
bvio
.
N
s criaremos um
tens de navegao
http://pt.discovermeteor.com/pdf
<li>
est vendo
home
/new
activeRouteClass
respectivamente
chamam o
234/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
<template name="header">
<header class="navbar">
<div class="navbar-inner">
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-col
lapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<a class="brand" href="{{pathFor 'home'}}">Microscope</a>
<div class="nav-collapse collapse">
<ul class="nav">
<li class="{{activeRouteClass 'home' 'newPosts'}}">
<a href="{{pathFor 'newPosts'}}">New</a>
</li>
<li class="{{activeRouteClass 'bestPosts'}}">
<a href="{{pathFor 'bestPosts'}}">Best</a>
</li>
{{#if currentUser}}
<li class="{{activeRouteClass 'postSubmit'}}">
<a href="{{pathFor 'postSubmit'}}">Submit Post</a>
</li>
<li class="dropdown">
{{> notifications}}
</li>
{{/if}}
</ul>
<ul class="nav pull-right">
<li>{{loginButtons}}</li>
</ul>
</div>
</div>
</header>
</template>
http://pt.discovermeteor.com/pdf
235/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Template.header.helpers({
activeRouteClass: function(/* route names */) {
var args = Array.prototype.slice.call(arguments, 0);
args.pop();
var active = _.any(args, function(name) {
return Router.current().route.name === name
});
}
});
Showingtheactivepage
http://pt.discovermeteor.com/pdf
236/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
ArgumentosdeAjudantes
N
tag de Handlerbar
E como voc
voc
tamb
receb
Neste
agora
pode claro passar argumentos nomeados espec ficos para sua funo
m pode passar um n
ltimo caso
voc
arguments
nimos e
pop()
arguments
em
Para cada
rota
teste
tem de navegao
o ajudante
any()
activeRouteClass
).
, any()
Finalmente
&& myString
retorna
retornar
true .
onde
false
myString .
retorna
Commit136
Ver no GitHub
Lanar Instncia
http://pt.discovermeteor.com/pdf
voc
ver
es no momento certo
237/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
PublicaesAvanadas
Agora voc
13.5
SIDEBAR
es e assinaturas interagem
PublicandoumaColeoMltiplasVezes
e n
,
es
_publishCursor
faz para n
s exatamente
es do cliente e do
os fez
_publishCursor
es mais
prios sites
Primeiro
quando n
s publicamos
.
,
Outro caso similar seria publicar uma viso geral de um conjunto grande de documentos
http://pt.discovermeteor.com/pdf
nico
tem
238/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Publishingacollectiontwice
Meteor.publish('allPosts', function() {
return Posts.find({}, {fields: {title: true, author: true}});
});
Meteor.publish('postDetail', function(postId) {
return Posts.find(postId);
});
postId
es
usando
autorun
fica
e os
http://pt.discovermeteor.com/pdf
239/261
1/8/2015
Voc
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
por
allPosts
postDetail
tamb
).
Entretanto
Meteor toma conta de fundir os campos e assegurar que no haja nenhum artigo duplicado
Isto
timo
,
n
estamos lidando com objetos de informao que que tem a exata quantidade de informao
para n
artigo
Entretanto
nico
quando n
s renderizamos a pgina de um
Claro
s precisamos tomar
conta no cliente para no se esperar todos os campos estarem dispon veis de todos os artigos
neste caso
isto
organizar os
es
Voc
mas
tens diferentemente
Meteor.publish('newPosts', function(limit) {
return Posts.find({}, {sort: {submitted: -1}, limit: limit});
});
Meteor.publish('bestPosts', function(limit) {
return Posts.find({}, {sort: {votes: -1, submitted: -1}, limit: limit});
});
server publications js
AssinandoumaPublicaoMltiplasVezes
assin la m
ltiplas vezes
s assinamos publicao
assinar m
nica publicao
mas
Em Microscope
criar uma
Alis voc
posts
Por
ltiplas vezes
s no possamos
http://pt.discovermeteor.com/pdf
240/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Por exemplo
na mem
Subscribingtwicetoonepublication
nica publicao
Meteor.publish('posts', function(options) {
return Posts.find({}, options);
});
E n
ltiplas vezes
Na verdade isto
mais ou menos
http://pt.discovermeteor.com/pdf
241/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
diferentes
um conjunto
diferente
de documentos
mas fundamentalmente
puxado da coleo
posts
cada vez
MltiplasColeesnumanicaAssinatura
Diferente de bancos de dados tradicionais relacionais como MySQL que trabalham com joins
jun
es
),
embutimento
agora
e at
nico que o
Entretanto
supomos que n
primeira pgina
Este cenrio de uso apresenta uma boa razo para embutir comentrios nos artigos
verdade
Claro que n
coleo
Desnormalizao
Mas como n
ao fazer tanto n
com cole
s deles
).
e na
Comments
nos livrando da
es separadas
Mas alis h um truque envolvendo assinaturas que torna poss vel embutir nossos
http://pt.discovermeteor.com/pdf
es separadas
242/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Vamos supor que junto com a nossa lista de artigos da pgina inicial
,
n
s gostar amos de
Seria dif cil conseguir isso com uma publicao de comentrios independente
vamos dizer
os
10
especialmente
).
mais recentes
ter amos de escrever uma publicao que se parecesse com algo assim
Twocollectionsinonesubscription
Meteor.publish('topComments', function(topPostIds) {
return Comments.find({postId: topPostIds});
});
http://pt.discovermeteor.com/pdf
243/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
topPostIds
mudasse
.
N
mas n
s podemos ter
s tamb
publicao
Meteor.publish('topPosts', function(limit) {
var sub = this, commentHandles = [], postHandle = null;
Note que n
enviamos mensagens ao
precisamos pedir a
sub
s mesmos
_publishCursor
http://pt.discovermeteor.com/pdf
via
para faz
.added()
lo por n
j que n
e amigos
).
s manualmente
Ento n
s no
s ao retornar um cursor
244/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Agora
s publicamos um artigo n
s tamb
m automaticamente publicamos os
pacote
publish-with-relations
no Atmosphere
voc
pode tamb
m checar o
Ligandocoleesdiferentes
se n
s no usamos o
Bem
fonte no servidor precisa para ter o mesmo nome como alvo na coleo no cliente
Onecollectionfortwosubscriptions
http://pt.discovermeteor.com/pdf
245/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Suponha que n
cada
conte
do
Por exemplo
tamb
video
link
timestamp
ou apenas texto
E apesar que n
nica coleo
transformar essa
'resources' , usando
type
um atributo
e t tulo
m ligeiramente diferentes em
nica coleo
nica coleo em m
Resources
ltiplas cole
es
no servidor
..
etc
s poder amos
Meteor.publish('videos', function() {
var sub = this;
var videosCursor = Resources.find({type: 'video'});
Meteor.Collection._publishCursor(videosCursor, sub, 'videos');
_publishCursor
s estamos dizendo ao
o cursor faria
publicar de
mas ao inv
'resources'
s de publicar a coleo
para
resources
para o cliente
s podemos
'videos' .
Em qualquer caso
poss vel
http://pt.discovermeteor.com/pdf
246/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Animaes
14
Entretanto
experi
usaremos anima
Meteor&oDOM
).
Meteor
(
(
).
s precisamos
a coleo de
uma limitao do pr
prio DOM
nova posio
es
pia
( ')
B
antes do elemento A
ao mov
'
Eles podem
Meteor na
m criado B
no do
o rec
),
).
graas reatividade
Ento
voc
o que
es p
2,
e p
uma
),
respectivamente
1.
2.
3.
4.
5.
6.
Delete B
'
Crie B
antes de A no DOM
Mova B
'
para p
Mova A para p
Anime A para p
'
Anime B para p
http://pt.discovermeteor.com/pdf
247/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
http://pt.discovermeteor.com/pdf
248/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Swtichingtwoposts
teletransportando
3 4
e
s no estamos animando A e B
'
J que isto
es mas
instantneo
dar a iluso de
Felizmente
Al
m disso
5 6
nos passos
devidos lugares
passos
es
3 4,
Para que a
ao
para n
ento n
6.
tudo que n
1&2
s estamos fazendo
TimingCerto
At
agora n
3 4,
Para os passos
no nosso caso
5 6
e
a resposta
na callback de template
no mesmo lugar
minutos
minutos
se voc
dissesse a um
tem de esperar at
simultaneamente
aconteceria
do Meteor dentro do
).
ide perfeitamente l
Ento se voc
rendered
ranque
andr
post_item.js , a qual ativada toda vez que uma propriedade do artigo muda
administrador
Os passos
s falamos sobre como animar nossos artigos mas no sobre quando anim los
minutos
10
minutos completos
e ento diz
lo para voltar
se n
voc
es
Em outras palavras
http://pt.discovermeteor.com/pdf
249/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
O Meteor no prov
uma callback
la usando
Meteor.defer() , a qual simplesmente recebe uma funo e adia sua execuo apenas o
PosicionamentoCSS
territ
rio CSS
mudadas ou animadas
Elementos estaticamente
da pgina
m se encaixa no fluxo
dar ao elemento
posicionado absoluta
relativamente
mas se voc
.
N
s j tomamos conta
precisaria fazer
.post{
position:relative;
transition:all 300ms 0ms ease-in;
}
5 6
bem fceis
tudo que n
s precisamos fazer
configurar
http://pt.discovermeteor.com/pdf
es
top
para
0px
normais
250/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
nico desafio
es
Em outras palavras
o contrabalano correto
passos
simplesmente a posio pr
3 4
e
em
Mas isto no
via do artigo
Posio:absoluta
N
absolutamente
position:absolute
m usar
naturalmente
ao inv
Consequentemente
posicionamento relativo
RecordaoTotal
lembrar
sua posio pr
via
'
Felizmente o Meteor vem nos resgastar nos dando acesso ao objeto instncia do template na
callback
, this
No corpo da callback
ocorr
s faremos
recriado
Desta forma
http://pt.discovermeteor.com/pdf
es
nico a esta
Ento o que n
e ento armazen la
deletado e
s devemos anim lo
251/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
s da
propriedade
RanqueandoArtigos
j que
mas este
uma conseq
ranque
Se n
Note que n
o raque
ranque
no pr
).
es
j que
vulgo
newPosts
topPosts , mas
Ento
rank
s inseriremos
no
o administrador de template
postList :
Template.postsList.helpers({
postsWithRank: function() {
this.posts.rewind();
return this.posts.map(function(post, index, cursor) {
post._rank = index;
return post;
});
}
});
list js
Ao inv
limit: postsHandle.limit()})
http://pt.discovermeteor.com/pdf
_rank
vio
posts , postsWithRank
252/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
postsList
tamb
<template name="postsList">
<div class="posts">
{{#each postsWithRank}}
{{> postItem}}
{{/each}}
{{#if nextPath}}
<a class="load-more" href="{{nextPath}}">Load more</a>
{{/if}}
</div>
</template>
list html
Sejabom,Rebobine
O Meteor
Mas um
de seus utilitrios parece um retrocesso aos dias dos VCRs e gravadores em v deo
cassete
rewind() .
a funo
forEach() , map()
ou
fetch() , voc
precisar rebobinar o cursor depois antes que ele esteja pronto para ser utilizado de
novo
E em alguns casos
preventivamente ao inv
rewind()
o cursor
s de arriscar um erro
Juntandotudo
administrador do
post_item.js
http://pt.discovermeteor.com/pdf
para a nossa l
gica de animao
rendered
do
253/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Template.postItem.helpers({
//...
});
Template.postItem.rendered = function(){
// animate post from previous position to new position
var instance = this;
var rank = instance.data._rank;
var $this = $(this.firstNode);
var postHeight = 80;
var newPosition = rank * postHeight;
// if element has a currentPosition (i.e. it's not the first ever render)
if (typeof(instance.currentPosition) !== 'undefined') {
var previousPosition = instance.currentPosition;
// calculate difference between old position and new position and send e
lement there
var delta = previousPosition - newPosition;
$this.css("top", delta + "px");
}
};
Template.postItem.events({
//...
});
/ _
item js
Commit141
Ver no GitHub
Lanar Instncia
http://pt.discovermeteor.com/pdf
ncia
254/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
na callback
currentPosition
s configuramos a propriedade
na instncia do template
do fragmento de template
Mas isto no
um problema j que n
Voc
s no estamos interessados
AnimandoNovosArtigos
uma animao
Isto
2.
ainda
s no temos realmente
Ao inv
Meteor
1.
new post
mas n
O problema
rendered
que a callback
do
inserido no DOM
Apenas o caso
ilumine como uma rvore de natal toda vez que a informao mudar
),
renderizao
bloco
else :
ento n
http://pt.discovermeteor.com/pdf
a qual
e no
apenas definida ap
s a primeira
rendered
e adicionar um
255/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Template.postItem.helpers({
//...
});
Template.postItem.rendered = function(){
// anima o artigo da posio prvia para a nova posio
var instance = this;
var rank = instance.data._rank;
var $this = $(this.firstNode);
var postHeight = 80;
var newPosition = rank * postHeight;
};
Template.postItem.events({
//...
});
/ _
item js
Commit142
Fade items in when they are drawn
Ver no GitHub
http://pt.discovermeteor.com/pdf
Lanar Instncia
256/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
removeClass("invisible")
Note que a
presente no elemento
que n
s adicionamos na funo
defer()
.invisible
rodar
estiver
CSS&JavaScript
Voc
top .
como n
s fizemos para
.invisible
Isto
porque para
opacity
para
diretamente
aqui n
.
,
classe aqui
uma boa id
J que
aplicativo e experimente
.post.invisible
functions
E agora voc
tamb
s quer amos
.
es
Rode seu
.post
Dica
CSS easing
http://pt.discovermeteor.com/pdf
257/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
VocabulrioMeteor
14.5
SIDEBAR
Cliente
Quando falamos do Cliente
utilizadores
estamos a referir c
ou algo to
Coleo
cliente e servidor
As Cole
es t
m um nome
posts , e normalmente
elas
Computao
Uma computao
um bloco de c
Sesso
digo que corre cada vez que uma fonte de dados reativa de
por exemplo
uma varivel de
para ela
Cursor
Um cursor
cursor no
No cliente
um
removidos ou atualizados
DDP
DDP
http://pt.discovermeteor.com/pdf
es e fazer chamadas a M
de Meteor
todos
o protocolo de
O DDP foi
258/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
rico
aplica
Deps
Deps
Deps
Documento
O Mongo
das cole
podem
es so chamados
no entanto
documentos
conter fun
es
com uma
que no
_id , que
s do DDP
Ajudante
Quando um template precisa de renderizar algo mais complexo que uma propriedade de um
processo de renderizar
CompensaodeLatncia
uma t
todos no cliente
para evitar
Mtodo
Um M
todo de Meteor
alguma l
Lat
com
es nas cole
es e suportar Compensao de
ncia
MiniMongo
semelhante de Mongo
http://pt.discovermeteor.com/pdf
chamada
259/261
1/8/2015
MiniMongo
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
para indicar que
completamente em mem
.
ria
Pacote
Um pacote Meteor pode consistir de
1.
C
2.
C
3.
4.
Instru
).
Um pacote
que
Publicao
Uma publicao
As publica
es so definidas no servidor
Servidor
O servidor Meteor
. .
bibliotecas de Meteor
servidor Meteor
e do c
Consiste de todas as
).
Quando voc
que tamb
inicia um
iniciada
Sesso
A Sesso em Meteor
Subscrio
http://pt.discovermeteor.com/pdf
260/261
1/8/2015
Discover Meteor Building Real-Time JavaScript Web Apps Sacha Greif & Tom Coleman
Uma subscrio
A subscrio
digo que corre no navegador que comunica com uma publicao no servidor e mant
dados sincronizados
m os
Template
Um template
Handlebars
um m
gica
Por omisso
Meteor suporta
no futuro
ContextodeDadosdoTemplate
Quando um template
renderizado
JavaScript objects
POJOs
),
- -
http://pt.discovermeteor.com/pdf
apesar de poderem
.
es
261/261