Use Backbone.js para acelerar as interações

Autor: Monica Porter
Data De Criação: 13 Marchar 2021
Data De Atualização: 15 Poderia 2024
Anonim
Use Backbone.js para acelerar as interações - Criativo
Use Backbone.js para acelerar as interações - Criativo

Contente

Se você está procurando construir rapidamente uma pequena ferramenta JavaScript, provavelmente não está pensando em usar uma estrutura. Mais fácil hackear algum código jQuery em vez de instalar e aprender um novo framework, certo? Errado, Backbone.js é uma estrutura de cola super leve que se parece com o antigo JavaScript regular que você está acostumado a escrever.

Fazemos muitos protótipos estáticos aqui no ZURB, porque gostamos de poder clicar nas páginas sem ter que escrever nenhum código de back-end. Freqüentemente, colocávamos imagens de espaço reservado em um cinza monótono ou às vezes procurávamos no Flickr por imagens de amostra para nos ajudar a visualizar o que poderia aparecer no rascunho final. Isso até uma sexta-feira mágica, quando decidimos que seria incrível escrever algum JavaScript para resolver nossos problemas. Queríamos poder pesquisar e selecionar fotos no Flickr, diretamente das próprias imagens de espaço reservado. Nós o chamaríamos de FlickrBomb, e esta é a história de como o construímos usando o Backbone.js.


É altamente recomendável que você dê uma olhada rápida no FlickrBomb antes de ler. É um daqueles negócios do tipo "um clique vale mais que mil palavras". Vá em frente, vamos esperar.

Existem muitos frameworks JavaScript disponíveis atualmente, SproutCore, JavaScriptMVC, Spine, Sammy, Knockout. Mas gostamos do Backbone.js para este projeto específico por alguns motivos diferentes:

1. É leve (100% livre de gordura, na verdade)

  • em peso, com a última versão embalada sendo cerca de 4,6 kb
  • no código, tendo pouco mais de 1.000 linhas de código, não é terrivelmente difícil seguir um rastreamento de pilha até o interior sem perder sua mente

2. Parece JavaScript

  • porque é JavaScript, é isso e é tudo
  • ele usa jQuery, que até sua avó conhece hoje em dia

3. Persistência super simples


  • pronto para uso, ele persiste os dados em um back-end (via REST), mas, ao inserir um único plug-in, ele salva no armazenamento local
  • porque ele abstrai a API de persistência, poderíamos fazer com que ele persistisse em um back-end REST apenas removendo o plug-in de armazenamento local

Vamos começar então

Como Backbone.js é apenas JavaScript, tudo o que precisamos fazer é incluí-lo junto com Underscore.js na página. jQuery não é uma dependência rígida para o Backbone em si, mas vamos usá-lo, então vamos incluí-lo aqui. Também vincularemos o plug-in de armazenamento local, já que não queremos nos preocupar com a configuração de um back-end. Observe que estamos vinculando diretamente os arquivos aqui para simplificar, mas você deve sempre hospedar seus próprios ativos em produção.

script src = "http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"> / script> script src = "http://documentcloud.github.com/backbone/ backbone-min.js "> / script> script src =" http://documentcloud.github.com/underscore/underscore-min.js "> / script> script src =" https://raw.github.com/ jeromegn / Backbone.localStorage / master / backbone.localStorage-min.js "> / script>

Todo o código a seguir neste artigo é específico para nosso aplicativo, portanto, podemos incluí-lo em um arquivo app.js ou apenas embutido, se preferir. Apenas lembre-se de incluí-lo após o Backbone. O backbone permite abstrair partes de nosso aplicativo, para torná-los modulares para fácil reutilização e mais legíveis para outros. Para melhor ilustrar essa abstração, íamos explicar o design do FlickrBomb de baixo para cima, começando com os modelos e terminando com as visualizações.


Nosso primeiro modelo

A primeira tarefa a ser resolvida é puxar as fotos do Flickr. Modelar um FlickrImage no backbone é simples o suficiente, vamos criar um novo modelo chamado FlickrImage e adicionar alguns métodos para nos ajudar a obter polegares de diferentes tamanhos.

var FlickrImage = Backbone.Model.extend ({fullsize_url: function () {return this.image_url ('medium');}, thumb_url: function () {return this.image_url ('square');}, image_url: function ( size) {var size_code; switch (size) {case 'square': size_code = '_s'; break; // 75x75 case 'medium': size_code = '_z'; break; // 640 na caixa lateral mais longa 'grande ': size_code =' _b '; break; // 1024 no lado mais longo default: size_code =' ';} return "http: // farm" + this.get (' farm ') + ".static.flickr.com / "+ this.get ('server') +" / "+ this.get ('id') +" _ "+ this.get ('secret') + size_code +" .webp ";}})

Os modelos no Backbone são objetos que podem ser persistentes e têm algumas funções associadas a eles, bem como os modelos em outros frameworks MVC. A parte mágica dos modelos de Backbone é que podemos vincular eventos a atributos, de modo que, quando esse atributo mudar, possamos atualizar nossas visualizações para refletir isso. Mas estamos nos adiantando um pouco.

Quando puxarmos as fotos do Flickr, vamos obter informações suficientes para criar URLs para todos os tamanhos. No entanto, essa montagem é deixada para nós, então implementamos a função .image_url () que recebe um parâmetro de tamanho e retorna um link público. Como este é um modelo de backbone, podemos usar this.get () para acessar atributos no modelo. Portanto, com este modelo, podemos fazer o seguinte em outro lugar no código para obter a URL de uma imagem do Flickr.

flickrImage.image_url ('grande')

Muito conciso, hein? Como este modelo é específico para nosso aplicativo, adicionaremos algumas funções de wrapper para os tamanhos de imagem em tamanho real e miniatura.

Uma coleção de imagens

O FlickrBomb lida com coleções de imagens, não imagens únicas, e o Backbone tem uma maneira conveniente de modelar isso. A coleção apropriadamente chamada é o que usaremos para agrupar imagens do Flickr em um único espaço reservado.

var FlickrImages = Backbone.Collection.extend ({model: FlickrImage, key: flickrbombAPIkey, page: 1, fetch: function (keywords, success) {var self = this; success = success || $ .noop; this.keywords = palavras-chave || this.keywords; $ .ajax ({url: 'http://api.flickr.com/services/rest/', data: {api_key: self.key, format: 'json', método: 'flickr. photos.search ', tags: this.keywords, per_page: 9, page: this.page, license: flickrbombLicenseTypes}, dataType:' jsonp ', jsonp:' jsoncallback ', success: function (response) {self.add (response) .photos.photo); success ();}});}, nextPage: function (callback) {this.page + = 1; this.remove (this.models); this.fetch (null, callback);}, prevPage: function (callback) {if (this.page> 1) {this.page - = 1;} this.remove (this.models); this.fetch (null, callback);}});

Há algumas coisas a serem observadas aqui. Em primeiro lugar, o modelo atributo informa às coleções que tipo de modelo está coletando. Também temos alguns atributos que inicializamos para uso posterior: key é nossa chave de API do Flickr, você deseja substituir flickrbombAPIkey pela string de sua própria chave de API do Flickr. Obter uma chave de API do Flickr é gratuito e fácil, basta seguir este link: www.flickr.com/services/api/misc.api_keys.html. O atributo de página é a página atual das fotos do Flickr em que estamos.

O grande método aqui é .fetch (), que abstrai os detalhes da extração de fotos da API do Flickr. Para evitar problemas com solicitações entre domínios, estamos usando JSONP, que é compatível com a API do Flickr e com o jQuery. Os outros parâmetros que estamos passando para a API devem ser autoexplicativos. De especial interesse são as funções de Backbone chamadas aqui. No retorno de chamada de sucesso, estamos usando .add (), uma função que pega uma matriz de atributos de modelo, cria instâncias de modelo a partir desses atributos e, em seguida, os adiciona à coleção.

As funções .nextPage () e .prevPage () primeiro alteram a página que queremos exibir,
use a função de coleção .remove (), para remover todos os modelos existentes do
coleção e, em seguida, chamar fetch para obter as fotos da página atual (que acabamos de
mudado).

The FlickrBombImage

Trabalhando nosso caminho de volta para cima, precisamos de mais um modelo para representar a imagem do espaço reservado, que consistirá em uma coleção de FlickrImages e a FlickrImage atual que foi selecionada. Chamaremos esse modelo de FlickrBombImage.

var localStorage = (supported_local_storage ())? new Store ("flickrBombImages"): null; var FlickrBombImage = Backbone.Model.extend ({localStorage: localStorage, inicializar: function () {_.bindAll (this, 'loadFirstImage'); this.flickrImages = new FlickrImages (); this.flickrImages.fetch (this.get ('palavras-chave'), this.loadFirstImage); this.set (id: this.get ("id")); this.bind ('alterar: src', this.changeSrc) ;}, changeSrc: function () {this.save ();}, loadFirstImage: function () {if (this.get ('src') === undefined) {this.set ({src: this.flickrImages. first (). image_url ()});}}});

Como esse modelo é responsável por rastrear a imagem atualmente selecionada entre os carregamentos de página, ele precisa saber qual armazenamento local usar.A primeira linha garantirá que haja suporte para armazenamento local e, em seguida, criará o armazenamento que usaremos para manter a imagem selecionada.

O backbone nos permite definir uma função .initialize () que será chamada quando uma instância do modelo for criada. Usamos essa função no FlickrBombImage para criar uma nova instância da coleção FlickrImages, passamos as palavras-chave que serão usadas para essa imagem e, em seguida, buscamos as imagens no Flickr.

A função .loadFirstImage () foi passada como um retorno de chamada a ser executado quando as imagens foram carregadas do Flickr. Como você provavelmente pode imaginar, esta função define a imagem atual como a primeira na coleção do Flickr. Isso não ocorre se a imagem atual já tiver sido definida.

Também usaremos callbacks de atributo do Backbone para disparar nossa função .changeSrc () quando o atributo src deste modelo mudar. Tudo o que esse retorno de chamada faz é chamar .save (), uma função de modelo de Backbone que persiste os atributos do modelo para qualquer camada de armazenamento que tenha sido implementada (em nosso caso localstore). Dessa forma, sempre que a imagem selecionada for alterada, ela será imediatamente persistida.

A Camada de Visualização

Agora que temos todo o código de back-end (bem, back-end de front-end) escrito, podemos montar as visualizações. As visualizações no Backbone são um pouco diferentes das visualizações em outras estruturas MVC tradicionais. Enquanto uma visualização normalmente se preocupa apenas com a apresentação, uma Visualização de Backbone também é responsável pelo comportamento. Isso significa que o seu modo de exibição não apenas define a aparência de algo, mas também o que ele deve fazer ao interagir com ele.

Uma visualização é comumente (mas nem sempre) vinculada a alguns dados e passa por três fases para gerar marcação de apresentação a partir desses dados:

1. O objeto View é inicializado e um elemento vazio é criado.
2. A função render é chamada, gerando a marcação para a vista, inserindo-a no elemento criado na etapa anterior.
3. O elemento é anexado ao DOM.

Pode parecer muito trabalhoso gerar alguma marcação, e ainda não chegamos à parte do comportamento da Visualização, mas é importante e aqui está o porquê. Cada vez que você modifica elementos que estão no DOM, você aciona algo chamado refluxo do navegador. Um refluxo é o navegador recalculando como tudo na página está posicionado. Os refluxos do navegador podem ser ruins para o desempenho se chamados em um evento de arrastar ou redimensionar, que dispara em um intervalo muito curto, mas pior, eles parecem desleixados. Com a manipulação de página complexa, você pode realmente ver os elementos sendo adicionados à página e o reposicionamento dos elementos afetados. Seguindo o padrão de inicialização, renderização e anexação do Backbone, você garante um único refluxo e as alterações na página serão perceptivelmente instantâneas, independentemente da complexidade da manipulação do elemento.

O FlickrBombImageView

var FlickrBombImageView = Backbone.View.extend ({tagName: "div", className: "flickrbombContainer", lock: false, template: _.template ('div id = "% = this.image.id.replace (" ", "")%> "... / div> '), inicializar: função (opções) {_.bindAll (this,' addImage ',' updateSrc ',' setDimentions ',' updateDimentions '); var keywords = options. img.attr ('src') .replace ('flickr: //', ''); this. $ el = $ (this.el); this.image = new FlickrBombImage ({keywords: keywords, id: options. img.attr ('id')}); this.image.flickrImages.bind ('adicionar', this.addImage); this.image.bind ('alterar: src', this.updateSrc);}, eventos: { "click .setupIcon": "clickSetup", "click .flickrbombFlyout a.photo": "selectImage", "click .flickrbombFlyout a.next": "nextFlickrPhotos", "click .flickrbombFlyout a.prev": "prevFlickrPhotos"}, renderizar: function () {$ (this.el) .html (this.template ()); this.image.fetch (); this.resize (); retornar isso;}, ...});

As funções desta visualização foram omitidas por questões de brevidade, o código-fonte em sua totalidade está disponível no GitHub: github.com/zurb/flickrbomb

No topo da View, temos alguns atributos específicos do Backbone. tagName e className são usados ​​para definir a tag e a classe que serão aplicadas ao elemento desta View. Lembre-se de que a etapa um da criação de View é criar um objeto e, como essa criação é controlada pelo Backbone, precisamos especificar o elemento e a classe. Observe que o Backbone tem padrões razoáveis; se omitirmos esses atributos, um div é usado por padrão e nenhuma classe será aplicada a menos que você especifique uma.

O atributo template é uma convenção, mas não obrigatório. Estamos usando aqui para especificar a função de modelo JavaScript que usaremos para gerar nossa marcação para esta visão. Usamos a função _.template () incluída no Underscore.js, mas você pode usar o mecanismo de modelagem de sua preferência, não o julgaremos.

Em nossa função .initialize (), estamos retirando a string de palavras-chave da tag de imagem e, em seguida, criando um modelo FlickrBombImage usando essas palavras-chave. Também estamos vinculando a função .addImage () a ser executada quando um FlickrImage é adicionado à coleção FlickrImages. Esta função irá anexar o FlickrImage recém-adicionado ao nosso menu desdobrável do seletor de imagens. A última e mais importante linha é vincular a função .updateSrc () para disparar quando o FlickrImage selecionado atualmente é alterado. Quando a imagem atual é alterada no modelo, esta função é executada, atualiza o atributo src do elemento de imagem e redimensiona e corta a imagem para caber nas dimensões especificadas pelo usuário.

eventos: {"click .setupIcon": "clickSetup", "click .flickrbombFlyout a.photo": "selectImage", "click .flickrbombFlyout a.next": "nextFlickrPhotos", "click .flickrbombFlyout a.prev": "prevFlickrPhotos "}

Seguindo .initialize () temos a parte do comportamento da View. O backbone fornece uma maneira conveniente de vincular eventos usando um objeto de eventos. O objeto de eventos usa o método jQuery .delegate () para fazer a vinculação real ao elemento View, de forma que, independentemente de qual manipulação você fizer no elemento dentro da view, todos os seus eventos vinculados ainda funcionarão. Funciona exatamente como jQuery .live (), exceto que, em vez de vincular eventos a todo o documento, você pode vinculá-los dentro do escopo de qualquer elemento. A chave de cada entrada no objeto de eventos consiste no evento e no seletor, o valor indica a função que deve ser associada a esse evento. Observe que .delegate () não funciona com alguns eventos como submit, consulte a documentação do jQuery .live () para uma lista completa de eventos suportados.

render: function () {$ (this.el) .html (this.template ()); this.image.fetch (); this.resize (); devolva isso;}

Por último, temos a função .render () que é responsável por criar nossa marcação e fazer qualquer trabalho adicional que não possa ser executado até que a marcação View tenha sido adicionada ao elemento View. Depois de renderizar nosso modelo, precisamos chamar .fetch () em nosso FlickrBombImage. .fetch () é uma função de Backbone que obtém a cópia mais recente do modelo da camada de persistência. Se tivéssemos salvado este modelo antes, .fetch () iria recuperar esses dados agora. Após a busca da imagem, precisamos chamar resize para posicioná-la corretamente.

The Home Stretch

Com todas as peças no lugar, tudo o que precisamos fazer agora é encontrar as imagens de espaço reservado na página e substituí-las pelas visualizações renderizadas do FlickrBombImage.

$ ("img [src ^ = 'flickr: //']") .each (function () {var img = $ (this), flickrBombImageView = new FlickrBombImageView ({img: img}); img.replaceWith (flickrBombImageView. render (). el);});

Este pequeno recorte precisa ser executado na parte inferior da página, ou em um retorno de chamada pronto para documento, para garantir que ele possa encontrar as imagens de espaço reservado que irá substituir. Usamos a convenção de especificar flickr: // [KEYWORD] no atributo src de uma tag de imagem para indicar que ela deve ser preenchida com imagens do Flickr. Encontramos elementos de imagem com um atributo src correspondente, criamos um novo FlickrBombImageView e, em seguida, substituímos a imagem pela nossa. Pegamos uma cópia da imagem original e passamos para nosso FlickrBombView, para que possamos puxar algumas opções de configuração adicionais que podem ter sido especificadas no elemento.

O resultado final de todo esse trabalho árduo é uma API muito simples para quem usa a biblioteca. Eles podem simplesmente definir tags de imagem usando a convenção flickr: //, soltar o código do FlickrBomb na parte inferior de sua página e bam, eles têm imagens de espaço reservado do Flickr.

Funciona muito bem com grandes aplicativos da web também

Temos um grande aplicativo da web chamado Notable, que foi escrito sem a preocupação de gerar conteúdo do lado do cliente. Quando queríamos tornar as seções do aplicativo turbinadas pela geração de conteúdo do lado do cliente, escolhemos o Backbone. Os motivos eram os mesmos: queríamos um framework leve para ajudar a manter o código organizado, mas não nos forçar a repensar o aplicativo inteiro.

Lançamos as mudanças no início deste ano com grande sucesso e temos cantado elogios aos Backbones desde então.

Recursos adicionais

Há muito mais no Backbone do que o que abordei neste artigo, a parte C (controlador) do MVC (controlador de visualização do modelo) para iniciantes, que na verdade é um R (roteador) na versão mais recente. E está tudo coberto na documentação do Backbone, uma manhã leve de sábado dizia:
documentcloud.github.com/backbone/

Se você gosta de tutoriais mais tradicionais, verifique o código muito bem documentado deste aplicativo de tarefas escrito no Backbone:
documentcloud.github.com/backbone/docs/todos.html

Mais Lendo
O que fazer se você esqueceu a senha do iTunes
Ler

O que fazer se você esqueceu a senha do iTunes

"Equeci a enha do iTune, quer dizer, a enha para fazer login na iTune tore. Tentei lembrá-la, ma nenhuma dela funcionou. Alguma ugetão, por favor?" O iTune é uma oluç...
Resolvido: Incapaz de atualizar o erro de senha no Windows
Ler

Resolvido: Incapaz de atualizar o erro de senha no Windows

"Conigo acear minha conta de uuário padrão no Window 10 em meu PC domético, ma não conigo atualizar a enha de minha conta de adminitrador de uuário. Digito a enha de admi...
As melhores dicas para o novo iPhone SE Keychain não liga
Ler

As melhores dicas para o novo iPhone SE Keychain não liga

O iPhone ou qualquer outro dipoitivo iO vem com um recuro iCloud Keychain que permite armazenar ua enha e credenciai de login nele. Então, quando você etá pedindo um pacote online ou pr...