socialgekon.com
  • Principal
  • Lucratividade E Eficiência
  • Eventos Coisas Para Fazer
  • Gestão De Engenharia
  • Design De Marca
Web Front-End

Um guia para construir seu primeiro aplicativo Ember.js

À medida que os aplicativos da web modernos fazem mais e mais no lado do cliente (o próprio fato de agora nos referirmos a eles como 'aplicativos da web' em oposição a 'sites da web' é bastante revelador), tem havido um interesse crescente em estruturas do lado do cliente . Existem muitos jogadores neste campo, mas para aplicativos com muitas funcionalidades e muitas partes móveis, dois deles se destacam em particular: Angular.js e Ember.js .

Já publicamos um [tutorial de Angular.js] [https://www.toptal.com/angular-js/a-step-by-step-guide-to-your-first-angularjs-app] abrangente, então nós ' vamos focar em Ember.js neste post, no qual construiremos um aplicativo Ember simples para catalogar sua coleção de músicas. Você será apresentado aos principais blocos de construção da estrutura e terá um vislumbre de seus princípios de design. Se você quiser ver o código-fonte durante a leitura, ele está disponível como rock-and-roll no Github .

O que vamos construir?

Esta é a aparência de nosso aplicativo Rock & Roll em sua versão final:



À esquerda, você verá que temos uma lista de artistas e, à direita, uma lista de músicas do artista selecionado (você também pode ver que tenho bom gosto musical, mas estou divagando). Novos artistas e músicas podem ser adicionados simplesmente digitando na caixa de texto e pressionando o botão adjacente. As estrelas ao lado de cada música servem para avaliá-la, à la iTunes.

Poderíamos dividir a funcionalidade rudimentar do aplicativo nas seguintes etapas:

  1. Clicar em ‘Adicionar’ adiciona um novo artista à lista, com um nome especificado pelo campo ‘Novo Artista’ (o mesmo se aplica às músicas de um determinado artista).
  2. Esvaziar o campo ‘Novo artista’ desativa o botão ‘Adicionar’ (o mesmo se aplica às músicas de um determinado artista).
  3. Clicar no nome de um artista lista suas músicas à direita.
  4. Clicar nas estrelas avalia uma determinada música.

Temos um longo caminho a percorrer para fazer isso funcionar, então vamos começar.

Rotas: a chave para o aplicativo Ember.js

Uma das características distintivas do Ember é a grande ênfase que ele dá aos URLs. Em muitas outras estruturas, ter URLs separados para telas separadas está ausente ou foi adicionado como uma reflexão tardia. No Ember, o roteador - o componente que gerencia urls e transições entre eles - é a peça central que coordena o trabalho entre os blocos de construção. Conseqüentemente, também é a chave para entender o funcionamento interno dos aplicativos Ember.

Aqui estão as rotas para nosso aplicativo:

App.Router.map(function() { this.resource('artists', function() { this.route('songs', { path: ':slug' }); }); });

Definimos uma rota de recurso, artists e um songs rota aninhada dentro dela. Essa definição nos dará as seguintes rotas:

Eu usei o ótimo plugin Ember Inspector (ele existe para cromada e Raposa de fogo ) para mostrar as rotas geradas de uma forma facilmente legível. Aqui estão as regras básicas para as rotas Ember, que você pode verificar para nosso caso particular com a ajuda da tabela acima:

  1. Existe um application implícito | rota.

    Isso é ativado para todos solicitações (transições).

  2. Existe um index implícito | rota.

    Isso é inserido quando o usuário navega até a raiz do aplicativo.

  3. Cada rota de recurso cria uma rota com o mesmo nome e cria implicitamente uma rota de índice abaixo dela.

    Esta rota de índice é ativada quando o usuário navega para a rota. Em nosso caso, artists.index é acionado quando o usuário navega para /artists.

  4. Uma rota aninhada simples (sem recurso) terá seu nome de rota primária como seu prefixo.

    A rota que definimos como this.route('songs', ...) terá artists.songs como seu nome. Ele é acionado quando o usuário navega para /artists/pearl-jam ou /artists/radiohead.

  5. Se o caminho não for fornecido, ele será considerado igual ao nome da rota.

  6. Se o caminho contiver um :, é considerado um segmento dinâmico .

    O nome atribuído a ele (no nosso caso, slug) corresponderá ao valor no segmento apropriado da url. O slug segmento acima terá o valor pearl-jam, radiohead ou qualquer outro valor que foi extraído do URL.

Mostra a lista de artistas

Em uma primeira etapa, construiremos a tela que exibe a lista de artistas à esquerda. Esta tela deve ser mostrada aos usuários quando eles navegam para /artists/:

Para entender como essa tela é renderizada, é hora de apresentar outro princípio de design abrangente do Ember: convenção sobre configuração . Na seção acima, vimos que /artists ativa o artists rota. Por convenção, o nome dessa rota objeto é ArtistsRoute. É responsabilidade desse objeto de rota buscar dados para o aplicativo renderizar. Isso acontece no gancho do modelo da rota:

App.ArtistsRoute = Ember.Route.extend({ model: function() { var artistObjects = []; Ember.$.getJSON('http://localhost:9393/artists', function(artists) { artists.forEach(function(data) { artistObjects.pushObject(App.Artist.createRecord(data)); }); }); return artistObjects; } });

Neste snippet, os dados são buscados por meio de uma chamada XHR do back-end e - após a conversão em um objeto de modelo - enviados para uma matriz que podemos exibir posteriormente. No entanto, as responsabilidades da rota não se estendem a fornecer lógica de exibição, que é tratada pelo controlador. Vamos dar uma olhada.

Hmmm - na verdade, não precisamos definir o controlador neste momento! Ember é inteligente o suficiente para gerar o controlador quando necessário e defina o controlador M.odel atributo para o valor de retorno do próprio gancho do modelo, ou seja, a lista de artistas. (Novamente, isso é o resultado do paradigma de 'convenção sobre configuração'.) Podemos descer uma camada e criar um modelo para exibir a lista:

{{#each model}} {{#link-to 'artists.songs' this class='list-group-item artist-link'}} {{name}} {{/link-to}} {{/each}} {{outlet}}

Se isso parece familiar, é porque o Ember.js usa Guidão modelos, que têm uma sintaxe e auxiliares muito simples, mas não permitem lógica não trivial (por exemplo, termos ORing ou ANDing em uma condicional).

No modelo acima, iteramos através do modelo (configurado anteriormente pela rota para um array que contém todos os artistas) e para cada item nele, renderizamos um link que nos leva ao artists.songs rota para esse artista. O link contém o nome do artista. O #each helper em Handlebars altera o escopo dentro dele para o item atual, então {{name}} sempre se referirá ao nome do artista que está atualmente sob iteração.

Rotas aninhadas para visualizações aninhadas

Outro ponto de interesse no trecho acima: {{outlet}}, que especifica slots no modelo onde o conteúdo pode ser renderizado. Ao aninhar rotas, o modelo para a rota externa de recurso é renderizado primeiro, seguido pela rota interna, que renderiza o conteúdo do modelo no {{outlet}} definido pela rota externa. Isso é exatamente o que acontece aqui.

Por convenção, todas as rotas renderizam seu conteúdo no modelo de mesmo nome. Acima, o data-template-name atributo do modelo acima é artists o que significa que será renderizado para a rota externa, artists. Ele especifica uma saída para o conteúdo do painel direito, em que a rota interna, artists.index renderiza seu conteúdo:

Select an artist.

Em resumo, uma rota (artists) renderiza seu conteúdo na barra lateral esquerda, seu modelo sendo a lista de artistas. Outra rota, artists.index renderiza seu próprio conteúdo no slot fornecido pelo artists modelo. Ele poderia buscar alguns dados para servir como seu modelo, mas, neste caso, tudo o que queremos exibir é texto estático, então não precisamos fazer isso.

Relacionado: 8 perguntas essenciais da entrevista sobre o Ember.js

Crie um artista

Parte 1: vinculação de dados

Em seguida, queremos ser capazes de criar artistas, não apenas olhar para uma lista chata.

Quando mostrei que artists template que renderiza a lista de artistas, trapacei um pouco. Cortei a parte superior para me concentrar no que é importante. Agora, vou adicionar de volta:

{{input type='text' class='new-artist' placeholder='New Artist' value=newName}} Add ...

Usamos um auxiliar Ember, input, com tipo de texto para renderizar uma entrada de texto simples. Nele, nós ligar o valor da entrada de texto para newName propriedade do controlador que faz backup deste modelo, ArtistsController. Por conseqüência, quando a propriedade value da entrada muda (em outras palavras, quando o usuário digita texto nela) o newName propriedade no controlador será mantida em sincronia.

Também informamos que o createArtist a ação deve ser disparada quando o botão é clicado. Finalmente, vinculamos a propriedade disabled do botão ao disabled propriedade do controlador. Então, como é o controlador?

App.ArtistsController = Ember.ArrayController.extend({ newName: '', disabled: function() { return Ember.isEmpty(this.get('newName')); }.property('newName') });

newName é definido como vazio no início, o que significa que a entrada de texto ficará em branco. (Lembra-se do que eu disse sobre vinculações? Tente alterar newName e veja como é refletido como o texto no campo de entrada.)

disabled é implementado de forma que, quando não houver texto na caixa de entrada, ela retornará true e assim o botão será desabilitado. O .property chamada no final torna isso uma “propriedade computada”, outra fatia deliciosa do bolo de brasa.

Propriedades computadas são propriedades que dependem de outras propriedades, que podem ser “normais” ou calculadas. O Ember armazena em cache o valor desses até que uma das propriedades dependentes mude. Em seguida, ele recalcula o valor da propriedade computada e o armazena em cache novamente.

Aqui está uma representação visual do processo acima. Para resumir: quando o usuário insere o nome de um artista, o newName atualizações de propriedades, seguidas de disabled propriedade e, por fim, o nome do artista é adicionado à lista.

Desvio: uma única fonte de verdade

Pense nisso por um momento. Com a ajuda de ligações e propriedades computadas, podemos estabelecer (modelar) dados como o única fonte de verdade . Acima, uma mudança no nome do novo artista aciona uma mudança na propriedade do controlador, que por sua vez aciona uma mudança na propriedade disabled. Conforme o usuário começa a digitar o nome do novo artista, o botão fica habilitado, como que por mágica.

Quanto maior o sistema, mais vantagem ganhamos com o princípio da 'fonte única da verdade'. Ele mantém nosso código limpo e robusto, e nossas definições de propriedade, mais declarativas.

Algumas outras estruturas também enfatizam que os dados do modelo sejam a única fonte da verdade, mas não vão tão longe quanto Ember ou deixam de fazer um trabalho tão completo. Angular, por exemplo, tem ligações bidirecionais - mas não tem propriedades calculadas. Ele pode “emular” propriedades computadas por meio de funções simples; o problema aqui é que ele não tem como saber quando atualizar uma “propriedade computada” e, portanto, recorre à verificação suja e, por sua vez, leva a uma perda de desempenho, especialmente notável em aplicativos maiores.

Se você deseja aprender mais sobre o assunto, recomendo que leia Postagem do blog do eviltrout para uma versão mais curta ou esta questão Quora para uma discussão mais longa na qual os principais desenvolvedores de ambos os lados participam.

Parte 2: manipuladores de ação

Vamos voltar para ver como o createArtist a ação é criada depois de disparada (após pressionar o botão):

App.ArtistsRoute = Ember.Route.extend({ ... actions: { createArtist: function() { var name = this.get('controller').get('newName'); Ember.$.ajax('http://localhost:9393/artists', { type: 'POST', dataType: 'json', data: { name: name }, context: this, success: function(data) { var artist = App.Artist.createRecord(data); this.modelFor('artists').pushObject(artist); this.get('controller').set('newName', ''); this.transitionTo('artists.songs', artist); }, error: function() { alert('Failed to save artist'); } }); } } });

Os manipuladores de ação precisam ser agrupados em um actions objeto e pode ser definido na rota, controlador ou vista. Escolhi defini-lo na rota aqui porque o resultado da ação não se limita ao controlador, mas sim, “global”.

Não há nada sofisticado acontecendo aqui. Depois que o back-end nos informa que a operação de salvamento foi concluída com sucesso, fazemos três coisas, em ordem:

  1. Adicione o novo artista ao modelo do modelo (todos os artistas) para que seja renderizado novamente e o novo artista apareça como o último item da lista.
  2. Limpe o campo de entrada com newName vinculativo, evitando que tenhamos que manipular o DOM diretamente.
  3. Transição para uma nova rota (artists.songs), passando no artista recém-criado como o modelo para essa rota. transitionTo é a maneira de se mover entre as rotas internamente. (O auxiliar link-to serve para fazer isso por meio da ação do usuário.)

Exibir músicas para um artista

Podemos exibir as músicas de um artista clicando no nome do artista. Passamos também no artista que vai se tornar o modelo do novo roteiro. Se o objeto do modelo for transmitido dessa forma, o model o gancho da rota não será chamado, pois não há necessidade de resolver o modelo.

A rota ativa aqui é artists.songs e, portanto, o controlador e o modelo serão ArtistsSongsController e artists/songs, respectivamente. Já vimos como o template é renderizado no outlet fornecido pelo artists modelo para que possamos nos concentrar apenas no modelo em questão:

(...) {{#each songs}} {{title}} {{view App.StarRating maxRating=5}} {{/each}}

Observe que eliminei o código para criar uma nova música, pois seria exatamente o mesmo que para criar um novo artista.

O songs propriedade é configurada em todos os objetos de artista a partir dos dados retornados pelo servidor. O mecanismo exato pelo qual isso é feito tem pouco interesse para a discussão atual. Por enquanto, é suficiente sabermos que cada música tem um título e uma classificação.

O título é exibido diretamente no modelo e a avaliação é representada por estrelas, por meio do StarRating Visão. Vamos ver isso agora.

Widget de classificação por estrelas

A avaliação de uma música fica entre 1 e 5 e é mostrada ao usuário por meio de uma visualização, App.StarRating. As visualizações têm acesso ao seu contexto (neste caso, a música) e seu controlador. Isso significa que eles podem ler e modificar suas propriedades. Isso está em contraste com outro bloco de construção do Ember, os componentes, que são controles isolados e reutilizáveis ​​com acesso apenas ao que foi passado para eles. (Também poderíamos usar um componente de avaliação com estrelas neste exemplo.)

Vamos ver como a visualização exibe o número de estrelas e define a avaliação da música quando o usuário clica em uma das estrelas:

App.StarRating = Ember.View.extend({ classNames: ['rating-panel'], templateName: 'star-rating', rating: Ember.computed.alias('context.rating'), fullStars: Ember.computed.alias('rating'), numStars: Ember.computed.alias('maxRating'), stars: function() { var ratings = []; var fullStars = this.starRange(1, this.get('fullStars'), 'full'); var emptyStars = this.starRange(this.get('fullStars') + 1, this.get('numStars'), 'empty'); Array.prototype.push.apply(ratings, fullStars); Array.prototype.push.apply(ratings, emptyStars); return ratings; }.property('fullStars', 'numStars'), starRange: function(start, end, type) { var starsData = []; for (i = start; i <= end; i++) { starsData.push({ rating: i, full: type === 'full' }); }; return starsData; }, (...) });

rating, fullStars e numStars são propriedades calculadas que discutimos anteriormente com disabled propriedade do ArtistsController. Acima, usei uma chamada macro de propriedade computada, cerca de uma dúzia das quais são definidas no Ember. Eles tornam as propriedades típicas computadas mais sucintas e menos sujeitas a erros (para gravação). Eu defino rating para ser a classificação do contexto (e, portanto, da música), enquanto eu defini tanto o fullStars e numStars propriedades para que possam ser lidas melhor no contexto do widget de classificação por estrelas.

O stars método é a atração principal. Ele retorna uma matriz de dados para as estrelas em que cada item contém um rating propriedade (de 1 a 5) e uma bandeira (full) para indicar se a estrela está cheia. Isso torna extremamente simples percorrê-los no modelo:

{{#each view.stars}} {{/each}}

Este snippet contém vários pontos importantes:

  1. Primeiro, o each helper designa que ele usa uma propriedade de visualização (em oposição a uma propriedade no controlador) prefixando o nome da propriedade com view.
  2. Em segundo lugar, o class atributo da tag span tem classes dinâmicas e estáticas atribuídas. Qualquer coisa com o prefixo : torna-se uma classe estática, enquanto full:glyphicon-star:glyphicon-star-empty notação é como um operador ternário em JavaScript: se a propriedade completa for verdadeira, a primeira classe deve ser atribuída; se não, o segundo.
  3. Finalmente, quando a tag é clicada, o setRating a ação deve ser disparada - mas o Ember irá procurá-la na vista, não na rota ou controlador, como no caso da criação de um novo artista.

A ação é assim definida na visualização:

App.StarRating = Ember.View.extend({ (...) actions: { setRating: function() { var newRating = $(event.target).data('rating'); this.set('rating', newRating); } } });

Obtemos a classificação de rating Atributo de dados que atribuímos no modelo e então o definimos como rating para a música. Observe que a nova classificação não é mantida no back-end. Não seria difícil implementar essa funcionalidade com base em como criamos um artista e é deixada como um exercício para o leitor motivado.

Resumindo tudo

Nós provamos vários ingredientes do referido bolo de brasa:

  • Vimos como as rotas são o ponto crucial das aplicações Ember e como elas servem como base para as convenções de nomenclatura.
  • Vimos como ligações de dados bidirecionais e propriedades computadas tornam nossos dados de modelo a única fonte de verdade e nos permitem evitar a manipulação direta de DOM.
  • E vimos como disparar e lidar com ações de várias maneiras e construir uma visualização personalizada para criar um controle que é não parte do nosso HTML.

Lindo, não é?

Leitura adicional (e observação)

Há muito mais em Ember do que eu poderia caber neste post sozinho. Se você gostaria de ver uma série de screencast sobre como eu construí uma versão um pouco mais desenvolvida do aplicativo acima e / ou aprender mais sobre o Ember, você pode inscreva-se na minha lista de discussão para obter artigos ou dicas semanalmente.

Espero ter aguçado seu apetite para aprender mais sobre Ember.js e que você vá muito além do aplicativo de amostra que usei nesta postagem. Conforme você continua a aprender sobre o Ember.js, certifique-se de dar uma olhada em nosso artigo sobre Ember Data para aprender a usar a biblioteca de dados ember . Divirta-se construindo!

Relacionado: Ember.js e os 8 erros mais comuns cometidos pelos desenvolvedores

Padrões de design Python: para código elegante e moderno

Processo Interno

Padrões de design Python: para código elegante e moderno
Como fazer um vídeo de lapso de tempo original com seu iPhone

Como fazer um vídeo de lapso de tempo original com seu iPhone

Filmagem

Publicações Populares
Como tirar fotos abstratas criativas com seu iPhone
Como tirar fotos abstratas criativas com seu iPhone
Construindo um aplicativo MVC com Spring Framework: um tutorial para iniciantes
Construindo um aplicativo MVC com Spring Framework: um tutorial para iniciantes
The Pearls Of Wisdom - As melhores cartas de acionistas que ninguém lê
The Pearls Of Wisdom - As melhores cartas de acionistas que ninguém lê
Novas diretrizes do Taleban geram medo sobre o futuro da liberdade de imprensa
Novas diretrizes do Taleban geram medo sobre o futuro da liberdade de imprensa
Conheça Phoenix: uma estrutura semelhante a Rails para aplicativos da Web modernos no Elixir
Conheça Phoenix: uma estrutura semelhante a Rails para aplicativos da Web modernos no Elixir
 
Otimizando o futuro dos esforços humanitários globais
Otimizando o futuro dos esforços humanitários globais
Não dê ouvidos aos clientes - Por que a pesquisa do usuário é importante
Não dê ouvidos aos clientes - Por que a pesquisa do usuário é importante
Veterinário do Texas despedido por matar gato com arco e flecha
Veterinário do Texas despedido por matar gato com arco e flecha
Explicação da entropia de software: causas, efeitos e soluções
Explicação da entropia de software: causas, efeitos e soluções
Na oferta de fiança, advogados defendem o casamento de Ghislaine Maxwell
Na oferta de fiança, advogados defendem o casamento de Ghislaine Maxwell
Categorias
África Do Oriente MédioAscensão Do RemotoPessoas E Equipes De ProdutoCiência De Dados E Bancos De DadosWeb Front-EndKpis E AnálisesDesign De IuInovaçãoArmazenandoFerramentas E Tutoriais

© 2023 | Todos Os Direitos Reservados

socialgekon.com