SlideShare ist ein Scribd-Unternehmen logo
1 von 35
Downloaden Sie, um offline zu lesen
Um framework Javascript para construção de
interfaces adaptativas em aplicações REST
Apoio
W3C Brazil Office | NiC.br | Microsoft Brasil Open Source
http://mira.tecweb.inf.puc-rio.br/
Olá, eu sou Ezequiel Bertti
• MSc Engenharia de Software para Web
• Arquiteto de Sistema
• Desenvolvedor FullStack
• https://twitter.com/ebertti
• https://github.com/ebertti
• https://br.linkedin.com/in/ebertti
• ebertti@gmail.com
EBertti, Ezeq, .exe, Exec, Zeq ou Zequinha
Bagagem
Simples/PHP/Java C#/Asp.net Python/Django Javascript/Backbone
Desktop
Web Backend Frontend
Bacharel Mestrado Pesquisa
0 1 2 3 4 5 6 7 8 9 10 11 12
Acadêmica
Foco
Profissional
Quantos dispositivos acessam sua
aplicação?
Alguns poucos...
A responsividade resolve?
As vezes SIM!
E nesses casos?
Qual o esforço necessário para
desenvolver a interface de uma
aplicação?
Qual a proporção de tempo? De linhas de código? De testes?
E depois de “pronto”? Como é dar manutenção?
Podemos dizer que é quase a metade de tudo
Tipicamente, a interface gráfica, representa cerca de 48% do código
fonte, requer cerca de 45% do tempo de desenvolvimento e de 50% do
tempo de aplicação, e atinge 37% do tempo de manutenção [1]
[1] BRAD A. MYERS, M. B. R. Survey on user interface programming
37%
50%
45%
48%
0% 20% 40% 60% 80% 100%
Manutenção
Aplicação
Desenvolvimento
Código Fonte
Interface Outros
Ferramentas para diminuir o tamanho do problema
Mas e quando a
regra de negócio
muda?
Quando o modelo de dados muda?
Quando uma validação muda?
Quando um bug é encontrado?
Como fazer para dar manutenção a tantas interfaces?
Mogiana Paulista[2] agradece
[2] Região com a maior produção de café no Brasil
Abordagem convencional para
construção de interface
URI Contexto Dado Exibição
Exemplo:
http://meudominio.com.br/feed/xbox-one
Parser: (assunto)/(subtipo)
Protocolo: http
Domain: meudominio.com.br
View: listar
Tipo: feed
Subtipo: xbox-one
SELECT * FROM feed WHERE subtipo == ‘xbox-one’;
<html>
<body>
<div id="feeds">
{% for feed in feeds %}
<div class="feed">
<img src="{{ feed.image }}"/>
<h3>
<a href="{{ feed.link }}">{{ feed.title }}</a>
</h3>
</div>
{% endfor %}
</div>
</body>
</html>
Atualizando as visualizações de feed com
novas regras
• Destacar tipos de feed com css
• External → out
• Internal → in
• Tweet → twt
• Alguns feeds podem não ter link
• Alguns feeds podem ter imagem, e
conter link, caso o feed tenha link
<html><body><div id="feeds">
{% for feed in feeds %}
<div class="feed
{% if feed.type == 'external' %} out
{% elif feed.type == 'internal' %} in
{% elif feed.type == 'tweet' %} twt
{% endif %}">
{% if feed.image %}
{% if feed.link %}
<a href="{{ feed.link }}">
<img src="{{ feed.image }}"/>
</a>
{% else %}
<img src="{{ feed.image }}"/>
{% endif %}
{% endif %}
<h3>
{% if feed.link %}
<a href="{{ feed.link }}">{{ feed.title }}</a>
{% else %}
{{ feed.title }}
{% endif %}
</h3>
</div>
{% endfor %}
</div></body></html>
<div id="feeds">
<div ng-repeat="feed in feeds" ng-class="['feed',
{ out:feed.type == 'external',
in:feed.type == 'internal',
twt:feed.type == 'tweet' }]">
<a ng-if="feed.link && feed.image">
<img ng-src="feed.image"/>
</a>
<img ng-hide="feed.link" ng-show="feed.image“ ng-src="feed.image"/>
<h3>
<a ng-if="feed.link" ng-href="feed.link">
{{ feed.title }}
</a>
<span ng-hide="feed.link">
{{ feed.title }}
</span>
</h3>
</div>
</div>
E com um framework moderno, não muda
mui
Você reparou que algo não
mudou?
A estrutura da comunicação
Como o MIRA pode ajudar?
Model Interface for REST Aplications
Interface dirigida por modelos utilizando
regras para adaptar as interfaces
Modelo de
dados
Seleção de
interface
Interface
Abstrata
Interface
concreta
Widgets
Concretos
Projetista
(analista/arquiteto/engenheiro)
UX
(desenvolvedor/designer)
Estrutura de uma interface com MIRA
Dado Contexto Interface Exibição
Exemplo:
http://mira.tecweb/#?URI=http://api.meudominio.com.br/feed/xbox-one
api.meudominio.com.br
var selection = [{ when: 'isFeed', abstract: 'feed‘ }];
var abstracts = [{
name: 'feed',
widgets: [
{ name:'feeds', datasource:'$data.items',
children: [
{ name:'feed', children:[
{name:'image', bind:'$data.image'},
{name:'title', bind:'$data.title'}
]}]}]}];
var conditions = [
{name: 'isFeed', validate:'$data.type == "feed"'},
{name: 'isExternal', validate:'$data.type == "external"'},
{name: 'isInternal', validate:'$data.type == "internal"'},
{name: 'isTweet', validate:'$data.type == "tweet"'},
{name: 'hasImage', validate:'$data.image != null'},
{name: 'hasLink', validate:'$data.link != null'},
];
var response = {
type: 'feed',
items: [
{
title: 'titulo',
link: 'url',
image: 'url_of_image',
type: 'internal || ' +
'external || ' +
'tweet || ... '
}
/* ... */
]};
var concrete = [{
name:"feed", maps: [
{ name:"feeds" },
{ name:"feed", class:'feed' },
{ name:"feed", when:'isExternal', class:'feed out' },
{ name:"feed", when:'isInternal', class:'feed int' },
{ name:"feed", when:'isTweet', class:'feed twt' },
{ name:"image", when:"hasImage", src:"$bind"},
{ name:"image", when:"hasImage,hasLink", widget:'ImageLink',
href:'navigate($data.link)', src:"$bind"},
{ name:"title", tag: 'h3', value:'$bind'},
{ name:"title", when:"hasLink", widget:'TitleLink',
value:'$bind', href:'navigate($data.link)'}
]}];
Um exemplo com a API REST do
GitHub
Condições e Seleção de Interface
var conditions = [{
name: 'isUser',
validate: '$data.login != null'
},{
name: 'hasDetail',
validate: '$bind != null'
},{
name: 'haveWatch',
validate: '$data.watchers_count > 0'
}];
var selection = [
{
when: 'isUser',
abstract: 'user'
}
];
var response = {
"login": "ebertti",
"id": 140394,
"avatar_url": "https://avatars.githubusercontent.com/u/140394?v=3",
"gravatar_id": "",
"url": "https://api.github.com/users/ebertti",
"html_url": "https://github.com/ebertti",
"followers_url": "https://api.github.com/users/ebertti/followers",
"following_url": "https://api.github.com/users/ebertti/following{/other_user}",
"gists_url": "https://api.github.com/users/ebertti/gists{/gist_id}",
"starred_url": "https://api.github.com/users/ebertti/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/ebertti/subscriptions",
"organizations_url": "https://api.github.com/users/ebertti/orgs",
"repos_url": "https://api.github.com/users/ebertti/repos",
"events_url": "https://api.github.com/users/ebertti/events{/privacy}",
"received_events_url": "https://api.github.com/users/ebertti/received_events",
"type": "User",
"site_admin": false,
"name": "Ezequiel Bertti",
"company": "AmazingWorks",
"blog": "www.amazingworks.com.br",
"location": "Armação dos Búzios, Rio de Janeiro, Brazil",
"email": "ebertti@gmail.com",
"hireable": null,
"bio": null,
"public_repos": 19,
"public_gists": 4,
"followers": 32,
"following": 23,
"created_at": "2009-10-15T21:39:13Z",
"updated_at": "2015-07-01T14:09:06Z"
};
https://api.github.com
/users/ebertti
Interface Abstrata
detail
box
Interface Concretastructure:[
{'user': ['avatar', {'detail': ['user_name', 'login', 'bio', 'blog', 'company', 'location']}]},
{'repository': ['repository_name', 'repository_description', {box: ['repository_watch']}]}
],
maps: [ { name: 'navigation', widget: 'BootstrapNavigation', value:'"GitHub"'},
{ name: 'navigation-list', widget: 'BootstrapNavigationList'},
{ name: 'navigation-list-item', widget: 'BootstrapNavigationListItem',
value:'$bind', href:'navigate($data.link)'},
{ name: 'content', widget: 'ProfileContainer' },
{ name: 'user', class:'clearfix' },
{ name: 'avatar', widget: 'ProfileImage', value:'$bind' },
{ name: 'detail', class:'col-xs-12 col-sm-8' },
{ name: 'user_name', tag: 'h2', value: '$bind' },
{ name: 'login', widget: 'ProfileDetail', detail: 'Login', value: '$bind'},
{ name: 'bio', widget: 'ProfileDetail', detail: 'Bio', value: '$bind'},
{ name: 'blog', widget: 'ProfileDetail', detail: 'Blog', value: '$bind'},
{ name: 'company', widget: 'ProfileDetail', detail: 'Company', value: '$bind'},
{ name: 'location', widget: 'ProfileDetail', detail: 'Location', value: '$bind'},
{ name: 'follows_panel', class:'clearfix' },
{ name: 'follows_title', tag: 'h3', class:'clearfix', value:'"Seguidores"'},
{ name: 'follows' },
{ name: 'follow', tag:'a', href: 'navigate($bind)'},
{ name: 'follow_avatar', widget:'BootstrapSimple', md:'1', xs:'2', img:'circle,responsive',
tag: 'img', src: '$bind + "s=80"', alt:'$data.login', title:'$data.login'},
{ name: 'repositories_panel', class:'clearfix' },
{ name: 'repositories_title', tag: 'h3', value:'"Repositórios"'},
{ name: 'repositories' },
{ name: 'repository', class:'media'},
{ name: 'repository_name', tag: 'h4', value: '$data.name', class:'media-heading'},
{ name: 'repository_description', tag: 'span', value: '$data.description'},
{ name: 'box', tag: 'ul', class:'nav nav-pills nav-stacked pull-right'},
{ name: 'repository_watch', widget: 'ProfileCount', icon:'eye-close', value:'$bind'},
{ name: 'repository_watch', widget: 'ProfileCount', icon:'eye-open',
value:'$bind', when:'haveWatch'},
{ name: 'footer', widget: 'TecWebRodape' }
{ name: 'repository_watch', tag: 'ul',
class:'nav nav-pills nav-stacked pull-right‘, children:[
{ name: 'count', widget: 'ProfileCount',
icon:'eye-close', value:'$bind'},
{ name: 'count', widget: 'ProfileCount',
icon:'eye-open', value:'$bind', when:'haveWatch'}
]}
Duas formas de resolver a
necessidade de widgets extras para
exibir a contagem de Watch
E como são tratados os eventos?
{name:'status', value:'Aguardando',
events:{click:'marcar_feito'}
},
{name:'status', value:'Feito', when:'isDone'}
events.marcar_feito = function(options){
options.$dataObj.set('feito', true);
};
Aguardando Feitoclick
conditions = [{
name: 'isDone',
validate:'$data.feito == true‘
}];
click Feito
Exemplo com eventos
var maps = [
{ name: 'input_tarefa', widget:'BootstrapFormControl',
input:{type:'text', events:{ keydown:'adicionar' },
placeholder:'Descrição da Tarefa'}},
{ name: 'feito', widget:'BootstrapIcon', value:'unchecked',
events: { click: 'marcar' }},
{ name: 'feito', when:'isFeito',
widget:'BootstrapIcon', value:'check',
events: { click: 'marcar' }},
{ name: 'editar', widget:'BootstrapIcon', value:'edit',
events: { click: 'habilitar_edicao' }},
{ name: 'remover', widget:'BootstrapIcon', value:'remove',
events: { click: 'remover' }},
{ name: 'imagem_tarefa', when:'hasLocation',
widget:'MapStatic', size:'450x200', class:'thumbnail',
value:'$data.tarefa.substring($data.tarefa.indexOf("@"))'},
{ name: 'tarefa', class:'lead', value:'$data.tarefa',
md:'8', events: { click:'habilitar_edicao' }},
{ name: 'tarefa', when:'inEdition',
widget:'BootstrapFormControl', md:8,
input:{ value:'$data.tarefa', events:{keydown:'editar'}}
},
{ name: 'tipo', alert:"warning", class:'row' },
{ name: 'tipo', when:'isFeito',
alert:"info", class:'row'},
];
event.marcar = function(options){
options.$dataObj.set('feito',
!options.$dataObj.get('feito'))
};
event.habilitar_edicao = function(options){
if(!options.$dataObj.get('$edit')) {
options.$dataObj.set('$edit', true);
} else {
options.$dataObj.set('$edit', undefined);
}
};
var conditions = [{
name: 'isFeito',
validate:
'$data.feito == true'},
{ name: 'hasLocation',
validate:
'$data.tarefa.indexOf("@") != -1'},
{ name: 'inEdition',
validate:
'$data.$edit != null'}];
E como eu crio meus widgets?
http://mira.tecweb.inf.puc-rio.br
var custom_widgets = {
TitleLink: function($parent, name, $context, options, callback) {
var element = document.createElement('h1');
element.id = name;
element.setAttribute('class', 'title');
var link = document.createElement('a');
link.setAttribute('href', options.href);
link.innerHTML = options.value;
element.appendChild(link);
$parent.append(element);
var $element = $(element);
var $link = $(link);
if(callback){
callback({
$children: $link,
$element: $element
})
}
}
};
Mira.Widget.register(custom_widgets);
var map = {
name: 'title', widget: 'TitleLink', value:'MIRA',
href: 'http://mira.tecweb.inf.puc-rio.br'
};
<h1>
<a href="http://mira.tecweb.inf.puc-rio.br">
MIRA
</a>
</h1>
MIRA
Mas não tem um jeito mais fácil
para construir estas estruturas de
interface do MIRA?
Ferramenta de edição para Interface Abstrata
http://ebertti.github.io/mira-ui
MIRA – Editor
http://tecweblab.github.io/mira-editor/
Feito por: João Victor Magela
Aqui estão mais exemplos de aplicações
Orientador:
Daniel Schwabe
LINKS
Exemplos:
http://mira.tecweb.inf.puc-rio.br/
Documentação em Português:
http://mira.tecweb.inf.puc-rio.br/docs
Código:
https://github.com/tecweblab/mira
http://mira.codeplex.com/
Ferramentas:
http://ebertti.github.io/mira-ui/
http://tecweblab.github.io/mira-editor/

Weitere ähnliche Inhalte

Was ist angesagt?

JQuery Alagoinhas Dev Day - UNEB
JQuery Alagoinhas Dev Day - UNEBJQuery Alagoinhas Dev Day - UNEB
JQuery Alagoinhas Dev Day - UNEBLuciano Borges
 
Palestra - Iniciando no Jquery
Palestra - Iniciando no JqueryPalestra - Iniciando no Jquery
Palestra - Iniciando no Jquerygrupoweblovers
 
Evento Front End SP - Arquitetura de Front
Evento Front End SP - Arquitetura de FrontEvento Front End SP - Arquitetura de Front
Evento Front End SP - Arquitetura de FrontMichel Ribeiro
 

Was ist angesagt? (6)

JQuery Alagoinhas Dev Day - UNEB
JQuery Alagoinhas Dev Day - UNEBJQuery Alagoinhas Dev Day - UNEB
JQuery Alagoinhas Dev Day - UNEB
 
Palestra - Iniciando no Jquery
Palestra - Iniciando no JqueryPalestra - Iniciando no Jquery
Palestra - Iniciando no Jquery
 
Evento Front End SP - Arquitetura de Front
Evento Front End SP - Arquitetura de FrontEvento Front End SP - Arquitetura de Front
Evento Front End SP - Arquitetura de Front
 
Java script aula 06 - dom
Java script   aula 06 - domJava script   aula 06 - dom
Java script aula 06 - dom
 
Java script aula 07 - j-query
Java script   aula 07 - j-queryJava script   aula 07 - j-query
Java script aula 07 - j-query
 
Introdução ao JQuery e AJAX
Introdução ao JQuery e AJAXIntrodução ao JQuery e AJAX
Introdução ao JQuery e AJAX
 

Ähnlich wie MIRA - Um framework Javascript para construção de interfaces adaptativas em aplicações REST

Simplificando o full stack - desenvolvimento web na prática
Simplificando o full stack - desenvolvimento web na práticaSimplificando o full stack - desenvolvimento web na prática
Simplificando o full stack - desenvolvimento web na práticaMarianna Cruz Teixeira
 
HTML & CSS - Aula 2
HTML & CSS - Aula 2HTML & CSS - Aula 2
HTML & CSS - Aula 2lucampos_si
 
Graph API - Desenvolvimento para Facebook
Graph API - Desenvolvimento para FacebookGraph API - Desenvolvimento para Facebook
Graph API - Desenvolvimento para FacebookDouglas V. Pasqua
 
Simplificando o Javascrip
Simplificando o JavascripSimplificando o Javascrip
Simplificando o JavascripMiquéias Amaro
 
jQuery - Visão Geral
jQuery - Visão GeraljQuery - Visão Geral
jQuery - Visão GeralKaio Valente
 
LambdaDay: Backbone.js
LambdaDay: Backbone.jsLambdaDay: Backbone.js
LambdaDay: Backbone.jsGiovanni Bassi
 
Programando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um FrameworkProgramando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um FrameworkPablo Dall'Oglio
 
Backbone.js nas trincheiras
Backbone.js nas trincheirasBackbone.js nas trincheiras
Backbone.js nas trincheirasLambda 3
 
Play Framework - FLISOL
Play Framework - FLISOLPlay Framework - FLISOL
Play Framework - FLISOLgrupoweblovers
 
Django: Desenvolvendo uma aplicação web em minutos
Django: Desenvolvendo uma aplicação web em minutosDjango: Desenvolvendo uma aplicação web em minutos
Django: Desenvolvendo uma aplicação web em minutosRodrigo Nossal
 
LPII_Aula_7-JQuery.pdf
LPII_Aula_7-JQuery.pdfLPII_Aula_7-JQuery.pdf
LPII_Aula_7-JQuery.pdfGabrielaMota46
 
Mini Curso - jQuery - FMU
Mini Curso - jQuery - FMUMini Curso - jQuery - FMU
Mini Curso - jQuery - FMUThiago Ericson
 
Meu primeiro tema de WordPress
Meu primeiro tema de WordPressMeu primeiro tema de WordPress
Meu primeiro tema de WordPressLuan Muniz
 
Desenvolvimento de Módulos Divi Builder
Desenvolvimento de Módulos Divi BuilderDesenvolvimento de Módulos Divi Builder
Desenvolvimento de Módulos Divi BuilderDaniel Paz
 

Ähnlich wie MIRA - Um framework Javascript para construção de interfaces adaptativas em aplicações REST (20)

Zend Framework
Zend FrameworkZend Framework
Zend Framework
 
Wicket 2008
Wicket 2008Wicket 2008
Wicket 2008
 
Simplificando o full stack - desenvolvimento web na prática
Simplificando o full stack - desenvolvimento web na práticaSimplificando o full stack - desenvolvimento web na prática
Simplificando o full stack - desenvolvimento web na prática
 
Aplicacoes Rapidas Para Web Com Django
Aplicacoes Rapidas Para Web Com DjangoAplicacoes Rapidas Para Web Com Django
Aplicacoes Rapidas Para Web Com Django
 
HTML & CSS - Aula 2
HTML & CSS - Aula 2HTML & CSS - Aula 2
HTML & CSS - Aula 2
 
Graph API - Desenvolvimento para Facebook
Graph API - Desenvolvimento para FacebookGraph API - Desenvolvimento para Facebook
Graph API - Desenvolvimento para Facebook
 
Simplificando o Javascrip
Simplificando o JavascripSimplificando o Javascrip
Simplificando o Javascrip
 
jQuery - Visão Geral
jQuery - Visão GeraljQuery - Visão Geral
jQuery - Visão Geral
 
LambdaDay: Backbone.js
LambdaDay: Backbone.jsLambdaDay: Backbone.js
LambdaDay: Backbone.js
 
Programando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um FrameworkProgramando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um Framework
 
Workshop Django
Workshop DjangoWorkshop Django
Workshop Django
 
Backbone.js nas trincheiras
Backbone.js nas trincheirasBackbone.js nas trincheiras
Backbone.js nas trincheiras
 
Play Framework - FLISOL
Play Framework - FLISOLPlay Framework - FLISOL
Play Framework - FLISOL
 
HTML + CSS
HTML + CSSHTML + CSS
HTML + CSS
 
Django: Desenvolvendo uma aplicação web em minutos
Django: Desenvolvendo uma aplicação web em minutosDjango: Desenvolvendo uma aplicação web em minutos
Django: Desenvolvendo uma aplicação web em minutos
 
LPII_Aula_7-JQuery.pdf
LPII_Aula_7-JQuery.pdfLPII_Aula_7-JQuery.pdf
LPII_Aula_7-JQuery.pdf
 
Mini Curso - jQuery - FMU
Mini Curso - jQuery - FMUMini Curso - jQuery - FMU
Mini Curso - jQuery - FMU
 
Python 07
Python 07Python 07
Python 07
 
Meu primeiro tema de WordPress
Meu primeiro tema de WordPressMeu primeiro tema de WordPress
Meu primeiro tema de WordPress
 
Desenvolvimento de Módulos Divi Builder
Desenvolvimento de Módulos Divi BuilderDesenvolvimento de Módulos Divi Builder
Desenvolvimento de Módulos Divi Builder
 

MIRA - Um framework Javascript para construção de interfaces adaptativas em aplicações REST

  • 1. Um framework Javascript para construção de interfaces adaptativas em aplicações REST Apoio W3C Brazil Office | NiC.br | Microsoft Brasil Open Source http://mira.tecweb.inf.puc-rio.br/
  • 2. Olá, eu sou Ezequiel Bertti • MSc Engenharia de Software para Web • Arquiteto de Sistema • Desenvolvedor FullStack • https://twitter.com/ebertti • https://github.com/ebertti • https://br.linkedin.com/in/ebertti • ebertti@gmail.com EBertti, Ezeq, .exe, Exec, Zeq ou Zequinha
  • 3. Bagagem Simples/PHP/Java C#/Asp.net Python/Django Javascript/Backbone Desktop Web Backend Frontend Bacharel Mestrado Pesquisa 0 1 2 3 4 5 6 7 8 9 10 11 12 Acadêmica Foco Profissional
  • 4. Quantos dispositivos acessam sua aplicação?
  • 9. Qual o esforço necessário para desenvolver a interface de uma aplicação? Qual a proporção de tempo? De linhas de código? De testes? E depois de “pronto”? Como é dar manutenção?
  • 10. Podemos dizer que é quase a metade de tudo Tipicamente, a interface gráfica, representa cerca de 48% do código fonte, requer cerca de 45% do tempo de desenvolvimento e de 50% do tempo de aplicação, e atinge 37% do tempo de manutenção [1] [1] BRAD A. MYERS, M. B. R. Survey on user interface programming 37% 50% 45% 48% 0% 20% 40% 60% 80% 100% Manutenção Aplicação Desenvolvimento Código Fonte Interface Outros
  • 11. Ferramentas para diminuir o tamanho do problema
  • 12. Mas e quando a regra de negócio muda? Quando o modelo de dados muda? Quando uma validação muda? Quando um bug é encontrado? Como fazer para dar manutenção a tantas interfaces?
  • 13. Mogiana Paulista[2] agradece [2] Região com a maior produção de café no Brasil
  • 15. URI Contexto Dado Exibição Exemplo: http://meudominio.com.br/feed/xbox-one Parser: (assunto)/(subtipo) Protocolo: http Domain: meudominio.com.br View: listar Tipo: feed Subtipo: xbox-one SELECT * FROM feed WHERE subtipo == ‘xbox-one’; <html> <body> <div id="feeds"> {% for feed in feeds %} <div class="feed"> <img src="{{ feed.image }}"/> <h3> <a href="{{ feed.link }}">{{ feed.title }}</a> </h3> </div> {% endfor %} </div> </body> </html>
  • 16. Atualizando as visualizações de feed com novas regras • Destacar tipos de feed com css • External → out • Internal → in • Tweet → twt • Alguns feeds podem não ter link • Alguns feeds podem ter imagem, e conter link, caso o feed tenha link <html><body><div id="feeds"> {% for feed in feeds %} <div class="feed {% if feed.type == 'external' %} out {% elif feed.type == 'internal' %} in {% elif feed.type == 'tweet' %} twt {% endif %}"> {% if feed.image %} {% if feed.link %} <a href="{{ feed.link }}"> <img src="{{ feed.image }}"/> </a> {% else %} <img src="{{ feed.image }}"/> {% endif %} {% endif %} <h3> {% if feed.link %} <a href="{{ feed.link }}">{{ feed.title }}</a> {% else %} {{ feed.title }} {% endif %} </h3> </div> {% endfor %} </div></body></html>
  • 17. <div id="feeds"> <div ng-repeat="feed in feeds" ng-class="['feed', { out:feed.type == 'external', in:feed.type == 'internal', twt:feed.type == 'tweet' }]"> <a ng-if="feed.link && feed.image"> <img ng-src="feed.image"/> </a> <img ng-hide="feed.link" ng-show="feed.image“ ng-src="feed.image"/> <h3> <a ng-if="feed.link" ng-href="feed.link"> {{ feed.title }} </a> <span ng-hide="feed.link"> {{ feed.title }} </span> </h3> </div> </div> E com um framework moderno, não muda mui
  • 18. Você reparou que algo não mudou?
  • 19. A estrutura da comunicação
  • 20. Como o MIRA pode ajudar? Model Interface for REST Aplications
  • 21. Interface dirigida por modelos utilizando regras para adaptar as interfaces Modelo de dados Seleção de interface Interface Abstrata Interface concreta Widgets Concretos Projetista (analista/arquiteto/engenheiro) UX (desenvolvedor/designer)
  • 22. Estrutura de uma interface com MIRA Dado Contexto Interface Exibição
  • 23. Exemplo: http://mira.tecweb/#?URI=http://api.meudominio.com.br/feed/xbox-one api.meudominio.com.br var selection = [{ when: 'isFeed', abstract: 'feed‘ }]; var abstracts = [{ name: 'feed', widgets: [ { name:'feeds', datasource:'$data.items', children: [ { name:'feed', children:[ {name:'image', bind:'$data.image'}, {name:'title', bind:'$data.title'} ]}]}]}]; var conditions = [ {name: 'isFeed', validate:'$data.type == "feed"'}, {name: 'isExternal', validate:'$data.type == "external"'}, {name: 'isInternal', validate:'$data.type == "internal"'}, {name: 'isTweet', validate:'$data.type == "tweet"'}, {name: 'hasImage', validate:'$data.image != null'}, {name: 'hasLink', validate:'$data.link != null'}, ]; var response = { type: 'feed', items: [ { title: 'titulo', link: 'url', image: 'url_of_image', type: 'internal || ' + 'external || ' + 'tweet || ... ' } /* ... */ ]}; var concrete = [{ name:"feed", maps: [ { name:"feeds" }, { name:"feed", class:'feed' }, { name:"feed", when:'isExternal', class:'feed out' }, { name:"feed", when:'isInternal', class:'feed int' }, { name:"feed", when:'isTweet', class:'feed twt' }, { name:"image", when:"hasImage", src:"$bind"}, { name:"image", when:"hasImage,hasLink", widget:'ImageLink', href:'navigate($data.link)', src:"$bind"}, { name:"title", tag: 'h3', value:'$bind'}, { name:"title", when:"hasLink", widget:'TitleLink', value:'$bind', href:'navigate($data.link)'} ]}];
  • 24. Um exemplo com a API REST do GitHub
  • 25. Condições e Seleção de Interface var conditions = [{ name: 'isUser', validate: '$data.login != null' },{ name: 'hasDetail', validate: '$bind != null' },{ name: 'haveWatch', validate: '$data.watchers_count > 0' }]; var selection = [ { when: 'isUser', abstract: 'user' } ]; var response = { "login": "ebertti", "id": 140394, "avatar_url": "https://avatars.githubusercontent.com/u/140394?v=3", "gravatar_id": "", "url": "https://api.github.com/users/ebertti", "html_url": "https://github.com/ebertti", "followers_url": "https://api.github.com/users/ebertti/followers", "following_url": "https://api.github.com/users/ebertti/following{/other_user}", "gists_url": "https://api.github.com/users/ebertti/gists{/gist_id}", "starred_url": "https://api.github.com/users/ebertti/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/ebertti/subscriptions", "organizations_url": "https://api.github.com/users/ebertti/orgs", "repos_url": "https://api.github.com/users/ebertti/repos", "events_url": "https://api.github.com/users/ebertti/events{/privacy}", "received_events_url": "https://api.github.com/users/ebertti/received_events", "type": "User", "site_admin": false, "name": "Ezequiel Bertti", "company": "AmazingWorks", "blog": "www.amazingworks.com.br", "location": "Armação dos Búzios, Rio de Janeiro, Brazil", "email": "ebertti@gmail.com", "hireable": null, "bio": null, "public_repos": 19, "public_gists": 4, "followers": 32, "following": 23, "created_at": "2009-10-15T21:39:13Z", "updated_at": "2015-07-01T14:09:06Z" }; https://api.github.com /users/ebertti
  • 27. Interface Concretastructure:[ {'user': ['avatar', {'detail': ['user_name', 'login', 'bio', 'blog', 'company', 'location']}]}, {'repository': ['repository_name', 'repository_description', {box: ['repository_watch']}]} ], maps: [ { name: 'navigation', widget: 'BootstrapNavigation', value:'"GitHub"'}, { name: 'navigation-list', widget: 'BootstrapNavigationList'}, { name: 'navigation-list-item', widget: 'BootstrapNavigationListItem', value:'$bind', href:'navigate($data.link)'}, { name: 'content', widget: 'ProfileContainer' }, { name: 'user', class:'clearfix' }, { name: 'avatar', widget: 'ProfileImage', value:'$bind' }, { name: 'detail', class:'col-xs-12 col-sm-8' }, { name: 'user_name', tag: 'h2', value: '$bind' }, { name: 'login', widget: 'ProfileDetail', detail: 'Login', value: '$bind'}, { name: 'bio', widget: 'ProfileDetail', detail: 'Bio', value: '$bind'}, { name: 'blog', widget: 'ProfileDetail', detail: 'Blog', value: '$bind'}, { name: 'company', widget: 'ProfileDetail', detail: 'Company', value: '$bind'}, { name: 'location', widget: 'ProfileDetail', detail: 'Location', value: '$bind'}, { name: 'follows_panel', class:'clearfix' }, { name: 'follows_title', tag: 'h3', class:'clearfix', value:'"Seguidores"'}, { name: 'follows' }, { name: 'follow', tag:'a', href: 'navigate($bind)'}, { name: 'follow_avatar', widget:'BootstrapSimple', md:'1', xs:'2', img:'circle,responsive', tag: 'img', src: '$bind + "s=80"', alt:'$data.login', title:'$data.login'}, { name: 'repositories_panel', class:'clearfix' }, { name: 'repositories_title', tag: 'h3', value:'"Repositórios"'}, { name: 'repositories' }, { name: 'repository', class:'media'}, { name: 'repository_name', tag: 'h4', value: '$data.name', class:'media-heading'}, { name: 'repository_description', tag: 'span', value: '$data.description'}, { name: 'box', tag: 'ul', class:'nav nav-pills nav-stacked pull-right'}, { name: 'repository_watch', widget: 'ProfileCount', icon:'eye-close', value:'$bind'}, { name: 'repository_watch', widget: 'ProfileCount', icon:'eye-open', value:'$bind', when:'haveWatch'}, { name: 'footer', widget: 'TecWebRodape' } { name: 'repository_watch', tag: 'ul', class:'nav nav-pills nav-stacked pull-right‘, children:[ { name: 'count', widget: 'ProfileCount', icon:'eye-close', value:'$bind'}, { name: 'count', widget: 'ProfileCount', icon:'eye-open', value:'$bind', when:'haveWatch'} ]} Duas formas de resolver a necessidade de widgets extras para exibir a contagem de Watch
  • 28. E como são tratados os eventos? {name:'status', value:'Aguardando', events:{click:'marcar_feito'} }, {name:'status', value:'Feito', when:'isDone'} events.marcar_feito = function(options){ options.$dataObj.set('feito', true); }; Aguardando Feitoclick conditions = [{ name: 'isDone', validate:'$data.feito == true‘ }]; click Feito
  • 29. Exemplo com eventos var maps = [ { name: 'input_tarefa', widget:'BootstrapFormControl', input:{type:'text', events:{ keydown:'adicionar' }, placeholder:'Descrição da Tarefa'}}, { name: 'feito', widget:'BootstrapIcon', value:'unchecked', events: { click: 'marcar' }}, { name: 'feito', when:'isFeito', widget:'BootstrapIcon', value:'check', events: { click: 'marcar' }}, { name: 'editar', widget:'BootstrapIcon', value:'edit', events: { click: 'habilitar_edicao' }}, { name: 'remover', widget:'BootstrapIcon', value:'remove', events: { click: 'remover' }}, { name: 'imagem_tarefa', when:'hasLocation', widget:'MapStatic', size:'450x200', class:'thumbnail', value:'$data.tarefa.substring($data.tarefa.indexOf("@"))'}, { name: 'tarefa', class:'lead', value:'$data.tarefa', md:'8', events: { click:'habilitar_edicao' }}, { name: 'tarefa', when:'inEdition', widget:'BootstrapFormControl', md:8, input:{ value:'$data.tarefa', events:{keydown:'editar'}} }, { name: 'tipo', alert:"warning", class:'row' }, { name: 'tipo', when:'isFeito', alert:"info", class:'row'}, ]; event.marcar = function(options){ options.$dataObj.set('feito', !options.$dataObj.get('feito')) }; event.habilitar_edicao = function(options){ if(!options.$dataObj.get('$edit')) { options.$dataObj.set('$edit', true); } else { options.$dataObj.set('$edit', undefined); } }; var conditions = [{ name: 'isFeito', validate: '$data.feito == true'}, { name: 'hasLocation', validate: '$data.tarefa.indexOf("@") != -1'}, { name: 'inEdition', validate: '$data.$edit != null'}];
  • 30. E como eu crio meus widgets? http://mira.tecweb.inf.puc-rio.br var custom_widgets = { TitleLink: function($parent, name, $context, options, callback) { var element = document.createElement('h1'); element.id = name; element.setAttribute('class', 'title'); var link = document.createElement('a'); link.setAttribute('href', options.href); link.innerHTML = options.value; element.appendChild(link); $parent.append(element); var $element = $(element); var $link = $(link); if(callback){ callback({ $children: $link, $element: $element }) } } }; Mira.Widget.register(custom_widgets); var map = { name: 'title', widget: 'TitleLink', value:'MIRA', href: 'http://mira.tecweb.inf.puc-rio.br' }; <h1> <a href="http://mira.tecweb.inf.puc-rio.br"> MIRA </a> </h1> MIRA
  • 31. Mas não tem um jeito mais fácil para construir estas estruturas de interface do MIRA?
  • 32. Ferramenta de edição para Interface Abstrata http://ebertti.github.io/mira-ui
  • 34. Aqui estão mais exemplos de aplicações
  • 35. Orientador: Daniel Schwabe LINKS Exemplos: http://mira.tecweb.inf.puc-rio.br/ Documentação em Português: http://mira.tecweb.inf.puc-rio.br/docs Código: https://github.com/tecweblab/mira http://mira.codeplex.com/ Ferramentas: http://ebertti.github.io/mira-ui/ http://tecweblab.github.io/mira-editor/

Hinweis der Redaktion

  1. Se apresentar!!!
  2. Falar números aproximados
  3. Falar das diferenças de cada