The goal of a front-end developer is to create clear, easy, fast pages and interfaces that will make people understand and care about the information, by putting it in context, expose its legitimacy or lack thereof, and reveal their implicit or explicit interconnection.
<!DOCTYPE html>
<html>
<head>
<meta charset=UTF-8>
<title>Olá pessoal do treinamento!</title>
</head>
<body>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Meu Blog</title>
</head>
<body>
<div>
<span>Header</span>
</div>
<div>
<div>
<div><a href="#">Link 1</a></div>
<div><a href="#">Link 2</a></div>
<div><a href="#">Link 3</a></div>
<div><a href="#">Link 4</a></div>
</div>
<div>
<input type="text">
<input type="submit" value="Pesquisar">
</div>
</div>
<div>
<div>
<p>Meu primeiro artigo</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Donec a diam lectus. Set sit amet ipsum mauris. Maecenas congue ligula as quam viverra nec consectetur ant hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur.</p>
<p>Subseção</p>
<p>Donec ut librero sed accu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor.</p>
<p>Pelientesque auctor nisi id magna consequat sagittis. Curabitur dapibus, enim sit amet elit pharetra tincidunt feugiat nist imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros.</p>
<p>Outra subseção</p>
<p>Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum soclis natoque penatibus et manis dis parturient montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est.</p>
<p>Vivamus fermentum semper porta. Nunc diam velit, adipscing ut tristique vitae sagittis vel odio. Maecenas convallis ullamcorper ultricied. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, is fringille sem nunc vet mi.</p>
<div>
<div>
Autor <a href="mailto:danilo.vaz@focusnetworks.com.br">Danilo Vaz</a>
</div>
</div>
</div>
<div>
<p>Posts relacionados</p>
<div>
<div href="#">Link 1</a></div>
<div><a href="#">Link 2</a></div>
<div><a href="#">Link 3</a></div>
<div><a href="#">Link 4</a></div>
<div><a href="#">Link 5.</a></div>
</div>
</div>
</div>
<div>
<p>©Copyright 2018 by Danilo Vaz. All rights reversed.</p>
</div>
</body>
</html>
<html>
<body>
<p>
Hello World
</p>
<div> <img src="example.png"/></div>
</body>
</html>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
p {
color: green;
}
.text {
font-size: 60px;
}
#text {
font-size: 60px;
}
/* presença de atributo */
p[class] {
color: red;
}
/* começa com */
p[class^="text-"] {
color: blue;
}
/* valor igual */
p[class="text"] {
color: blue;
}
/* pseudo-classe */
li:first-child {
color: red;
}
li:last-child {
color: blue;
}
/* descendente */
div.one i {
color: red;
}
div.two i {
color: green;
}
/* filho */
div.one > i {
color: red;
}
div.two > i {
color: green;
}
/* imediatamente sucede */
.one p + div {
border: 1px solid navy;
background: lightpink;
}
.two p + div p + p {
border: 1px solid navy;
background: lightsalmon;
}
/* sucede */
.one p ~ i {
color: red;
}
.two p + div i ~ p {
color: cyan;
}
Calcular especificidade:
1°.-) Conte a quantidade de atributos id no seletor;
2°.-) Conte a quantidade de atributos classe no seletor;
3°.-) Conte a quantidade de tag's HTML no seletor;
4°.-) Escreva as quantidades obtidas, da esquerda para a direita e
na mesma ordem em que foram levantados (id,classe,tag).
O número assim obtido é a
pontuação da especificidade da regra.
Normal flow
Float
Absolute
Static
Relative
Float
Fixed
Absolute
Block
Inline
None
Inline-Block
- Altere o exemplo do Blog para usar Flexbox;
- Altere o exemplo de Galeria para usar Flexbox;
Dicas: border-radius, border-shadow, pseudo-classe $=
null
undefined
boolean
number
string
*object
**symbol
null
== e ===
for
do...while
while
break
continue
for...in
for...of
- Criar uma To Do App, crie uma lista de tarefas/supermercado;
- Crie uma função que percorra a lista com uma estrutura de repetição e verifique se há itens iguais, se sim, remova-os do Objeto ou Array;
- Crie uma função que adicione itens à lista;
-Crie uma função que remova itens da lista.
// Verifiquem se tanto Node quanto NPM estão instalados
node --version
npm --version
// Configure proxy do NPM
npm config set http-proxy http://USER_EMBRAER:SENHA@lnx237in.sjk.emb:9090
npm config set https-proxy http://USER_EMBRAER:SENHA@lnx237in.sjk.emb:9090
// Instale o Ember (versão 2.15.1 do projeto)
npm install -g ember-cli@2.15.1
// Verificando se a instalação está correta
ember -v
ember new nome-do-projeto
ember serve
ou
ember s
|--app
|--config
|--node_modules
<outros arquivos...>
ember-cli-build.js
package.json
README.md
(router.js)
(ember-cli)
//ember generate ou ember g
ember g route posts
//Ember vai criar os arquivos
app/routes/posts.js
app/templates/posts.hbs
(ember-cli)
import Ember from 'ember';
export default Ember.Route.extend({
});
//Alterando nome da url
this.route('posts', { path: 'meus-posts' });
this.route('files', { path: 'arquivos' });
Router.map(function() {
this.route('posts', function() {
this.route('new');
this.route('post', { path: '/:post_id' });
});
});
(ember-cli)
//ember generate ou ember g
ember g model post
//app/models/post.js
import DS from 'ember-data';
export default DS.Model.extend({
});
Attributes
//app/models/profile.js
import DS from 'ember-data';
export default DS.Model.extend({
firstName: DS.attr('string'),
lastName: DS.attr('string'),
birthday: DS.attr('date'),
size: DS.attr('number'),
options: DS.attr({
defaultValue() {
return [];
}
}),
enabled: DS.attr('boolean', { defaultValue: false })
});
Relationships
//app/models/profile.js
import DS from 'ember-data';
export default DS.Model.extend({
firstName: DS.attr('string'),
files: DS.hasMany('file')
});
//app/models/file.js
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr('string'),
profile: DS.belongsTo('profile')
});
(ember-cli)
//ember generate ou ember g
ember g controller posts
//app/controllers/posts.js
import Ember from 'ember';
export default Ember.Controller.extend({
});
//app/controllers/posts.js
import Ember from 'ember';
export default Ember.Controller.extend({
title: "Minha lista de posts",
options: [1, 2, 3],
obj: {
item: "A"
}
});
//posts.hbs
<h1>{{title}}</h1>
<p>{{obj.item}}</p>
//carrega as rotas aninhadas
//**remover se não desejar esse comportamento**
{{outlet}}
(ember-cli)
//ember generate ou ember g
ember g component featured-files
//gera o arquivo featured-files.hbs em app/templates/components
//gera o arquivo featured-files.js em app/components
//featured-files.hbs em app/templates/components
{{outlet}}
//featured-files.js em app/components
import Ember from 'ember';
export default Ember.Component.extend({
});
//app/templates/posts.hbs
<p>Oi, <strong>{{firstName}} {{lastName}}</strong>!</p>
//app/controllers/posts.js
import Ember from 'ember';
export default Ember.Controller.extend({
firstName: 'Danilo',
lastName: 'Vaz'
});
condicional if
//app/templates/posts.hbs
{{#if person}}
<p>Bem vindo, <b>{{person.firstName}} {{person.lastName}}</b>!</p>
{{else}}
<p>Por favor, faça login</p>
{{/if}}
//app/controllers/posts.js
import Ember from 'ember';
export default Ember.Controller.extend({
person: {
firstName: "Danilo",
lastName: "Vaz"
}
});
condicional unless
//app/templates/posts.hbs
{{#unless person}}
<p>Por favor, faça login</p>
{{else}}
<p>Bem vindo, <b>{{person.firstName}} {{person.lastName}}</b>!</p>
{{/if}}
//app/controllers/posts.js
import Ember from 'ember';
export default Ember.Controller.extend({
person: {
firstName: "Danilo",
lastName: "Vaz"
}
});
loop
//app/templates/posts.hbs
<ul>
{{#each people as |person|}}
<li>Oi, {{person.name}}!</li>
{{/each}}
</ul>
//app/controllers/posts.js
import Ember from 'ember';
export default Ember.Controller.extend({
people: [{
name: "Danilo"
},{
name: "Mazella"
}]
});
loop com index
//app/templates/posts.hbs
<ul>
{{#each people as |person index|}}
<li>Oi, {{person.name}}, você é o número {{index}} da fila</li>
{{/each}}
</ul>
//app/controllers/posts.js
import Ember from 'ember';
export default Ember.Controller.extend({
people: [{
name: "Danilo"
},{
name: "Mazella"
}]
});
lista vazia
//app/templates/posts.hbs
<ul>
{{#each people as |person index|}}
<li>Oi, {{person.name}}, você é o número {{index}} da fila</li>
{{else}}
<p>Não há pessoas na lista</p>
{{/each}}
</ul>
//app/controllers/posts.js
import Ember from 'ember';
export default Ember.Controller.extend({
people: [{
name: "Danilo"
},{
name: "Mazella"
}]
});
link
//app/router.js
Router.map(function() {
this.route('files', function(){
this.route('show', { path: '/:photo_id' });
});
});
//app/templates/application.hbs
//localhost:4200/files/1
<ul>
<li>{{#link-to "about"}}Sobre{{/link-to}}</li>
{{#each files as |file|}}
<li>
{{#link-to "files.show" file}}
{{file.name}}
{{/link-to}}
</li>
{{/each}}
</ul>
text-fields
//app/templates/posts.hbs
{{input value="Danilo Vaz"}}
ou
{{input value=firstName"}}
//será renderizado assim
<input type="text" value="Danilo Vaz"/>
checkbox
//app/templates/posts.hbs
{{input type="checkbox" name="isAdmin" checked=isAdmin}}
textarea
//app/templates/posts.hbs
{{textarea value=text cols="80" rows="6"}}
debugger
//app/templates/posts.hbs
{{#each items as |item|}}
{{debugger}}
{{/each}}
(Controller, Route, Component)
import Ember from 'ember';
export default Ember.Component.extend({
title: "Minha lista de posts",
actions: {
showTitle() {
alert(this.get('title'));
}
}
});
(Controller, Route, Component)
<button {{action "showTitle"}}>Título da página</button>
Passando argumentos
import Ember from 'ember';
export default Ember.Component.extend({
actions: {
showTitle(title, number) {
alert(title);
alert(number);
}
}
});
(Controller, Route, Component)
<button {{action "showTitle" "Minha página" 3}}>Título da página</button>
send e closure action
import Ember from 'ember';
export default Ember.Controller.extend({
actions: {
showTitle(title, number) {
alert(title);
alert(number);
}
}
});
mock
import Ember from 'ember';
export default Ember.Route.extend({
model() {
return [{
id: '1',
firstName: 'Danilo'
},{
id: '2',
firstName: 'Tomster'
}]
}
});
mock
//app/templates/profiles.hbs
{{#each model as |profile|}}
{{profile.id}} - {{profile.firstName}}
{{/each}}
muitos models
import Ember from 'ember';
export default Ember.Route.extend({
model() {
return RSVP.hash({
posts: [{
id: '1',
title: 'Meu primeiro artigo'
},{
id: '2',
title: 'Meu segundo artigo'
}],
profiles: [{
id: '1',
firstName: 'Danilo'
},{
id: '2',
firstName: 'Tomster'
}]
});
}
});
AJAX
ember-way
convenções
ember g adapter application
//app/adapter/application.js
import DS from 'ember-data';
export default DS.JSONAPIAdapter.extend({
});
host
ember g adapter application
//app/adapter/application.js
import DS from 'ember-data';
export default DS.JSONAPIAdapter.extend({
host: 'https://minhaapi.com.br'
});
ember g adapter application
//app/adapter/application.js
import DS from 'ember-data';
import ENV from '../config/environment';
export default DS.JSONAPIAdapter.extend({
// Faz o tratamento de todas as chamadas de createRecord
// para que condiza com a nossa API
urlForCreateRecord(modelName, snapshot) {
return `${ENV.namespace}/reports/configurations?name=aircraft`;
},
// Faz o tratamento de todas as chamadas de query
// para que condiza com a nossa API
urlForQuery(query, modelName) {
return `${ENV.namespace}/reports/configurations`;
},
// Faz o tratamento de todas as chamadas de findRecord
// para que condiza com a nossa API
urlForFindRecord(id, modelName, snapshot) {
return `${ENV.namespace}/reports/configurations/${id}`;
},
// Faz o tratamento de todas as chamadas de updateRecord
// para que condiza com a nossa API
urlForUpdateRecord(id, modelName, snapshot) {
return `${ENV.namespace}/reports/configurations/${id}`;
},
// Faz o tratamento de todas as chamadas de deleteRecord
// para que condiza com a nossa API
urlForDeleteRecord(id, modelName, snapshot) {
return `${ENV.namespace}/reports/configurations/${id}`;
}
});
ember g serializer post
//app/serializers/post.js
import DS from 'ember-data';
export default DS.JSONAPISerializer.extend({
primaryKey: 'minhaid',
attrs: {
lastName: 'lastNameOfPerson'
}
});
//cria o arquivo app/services/shopping-cart.js
ember g service shopping-cart
//cria o arquivo app/services/shopping-cart.js
import Ember from 'ember';
export default Ember.Service.extend({
});
//app/components/cart-content.js
import Ember from 'ember';
import { inject as service } from '@ember/service';
export default Component.extend({
//injeta o service /app/services/shopping-cart.js
shoppingCart: service()
});
criando métodos
//cria o arquivo app/services/shopping-cart.js
import Ember from 'ember';
export default Ember.Service.extend({
items: null,
add(item) {
this.get('items').pushObject(item);
},
remove(item) {
this.get('items').removeObject(item);
}
});
chamando métodos
//app/components/cart-content.js
import Ember from 'ember';
export default Component.extend({
//injeta o service /app/services/shopping-cart.js
shoppingCart: Ember.inject.service(),
//ou
meuCarrinho: Ember.inject.service("shopping-cart"),
actions: {
addItem(item) {
this.get("shoppingCart").add(item);
}
}
});
exibindo informações do service
<ul>
{{#each shoppingCart.items as |item|}}
<li>
{{item.name}}
<button {{action "remove" item}}>Remover</button>
</li>
{{/each}}
</ul>
ember g helper capitalize
//app/helpers/capitalize.js
import Ember from 'ember';
export function capitalize([value, ...rest]) {
let str = value.split(" ");
for (let i = 0, x = str.length; i < x; i++) {
str[i] = str[i][0].toUpperCase() + str[i].substr(1);
}
return `${str.join(" ")}`;
}
export default Ember.Helper.helper(capitalize);
https://github.com/getify/You-Dont-Know-JS
https://www.amazon.com.br/Princ%C3%ADpios-Orienta%C3%A7%C3%A3o-Objetos-em-JavaScript/dp/8575223895
https://balinterdi.com/rock-and-roll-with-emberjs/
https://www.amazon.com.br/Single-Page-Applications-End-End/dp/1617290750
https://www.novatec.com.br/livros/css3/
https://novatec.com.br/livros/html5-2ed/
https://developer.mozilla.org/pt-BR/
https://guides.emberjs.com/release/
Linkedin: https://br.linkedin.com/in/danilovaz