Desenvolvendo Universal Apps com HTML/WinJS para Windows 8.1 – Parte 2

Olá pessoal!

Dando continuidade a nossa série de posts sobre “Desenvolvendo Universal Apps com HTML/WinJS para Windows”, iremos tratar as formas como podemos trabalhar com o compartilhamento de código entre Windows e Windows Phone para tirarmos maior proveito do nosso projeto Universal App Javascript.

Você pode acessar aqui o nosso primeiro post (Desenvolvendo Universal Apps com HTML/WinJS para Windows – Parte 1) no qual fizemos uma breve contextualização dos assuntos envolvidos com essa série e criamos nosso projeto Universal Apps usando Javascript.

Conforme citado no nosso primeiro post, temos duas categorias de compartilhamento: compartilhamento de código e compartilhamento de interface. Desses, o compartilhamento de código é o mais comum, onde costumamos ter um código Javascript que é compartilhado entre os aplicativos das duas plataformas. Ele funciona bem quando o código compartilhado se aplica tanto para Windows como Windows Phone. Mas e se parte desse código não for comum? Nesse mesmo post iremos ver como podemos, de uma forma simples, ter num arquivo comum o código que se aplica somente para Windows e Windows Phone.

Etapa 1 – Compartilhamento de Código: Código comum entre as duas plataformas

O projeto que criamos no post anterior apresenta um exemplo de compartilhamento de código. Nele temos o arquivo Shared/js/default.js.

Este é um exemplo da primeira forma de compartilhamento de código, que é aquela em que temos um código comum que é aplicável para as duas plataformas. E nesse caso não tem segredo. Vamos ver um exemplo.

Vamos começar alterando a interface do usuário para incluir um controle texto para ser feito bind declarativo (para saber mais veja o exemplo “Declarative binding sample“).

  1. Em Shared/paghes/home.html, incluir o seguinte código no lugar da linha <p>Content goes here</p>:
    	<div class="mainContent">
            <p>What's your name?</p>
            <input id="nameInput" type="text" />
            <button id="helloButton">Say "Hello"</button>
            <div id="greetingOutput" data-win-bind="textContent: greetings"></div>
        </div>
    	

    Nota:

    • Percebam que adicionamos os elementos HTML como se fosse uma página Web comum. Contudo, para o div id="greetingOutput" fizemos o bind declarativo especificando o atributo data=win-bind="textContent: greetings" que irá atualizar o conteúdo texto da div a partir do bind que iremos definir no nosso código compartilhado.
    • Ao executar o mesmo código tanto no Windows como no Wndows Phone, você irá notar que a interface será mostrada diferente em cada uma delas. Isso ocorre porque o CSS para cada plataforma define regras específicas de apresentação.
  2. O próximo passo é incluir o código Javascript para binding do elemento. Para tanto, vamos alterar o arquivo Shared/pages/home/home.js. Esse código vai ser aplicável para as duas plataformas, sem distinção.

  3. Primeiro vamos incluir o nosso modelo. Para tanto, vamos usar o conceito de namespace que permite englobar recursos debaixo de um único nome (para saber mais acesse “Organizando seu código com WinJS.Namespace“). Adicione o seguinte código no início do código Javascript, logo após a linha "use strict" (linhas em destaque):

        "use strict";
    
    	WinJS.Namespace.define("UniversalAppSample", {
            model: WinJS.Binding.as({
                greetings: ""
            })
        });
    	

    Nota:
    O namespace será referenciado por UniversalAppSample. Dentro dele especificamos a informação model que pode ser ligada (bind) a elementos na página. Para tanto usamos a função WinJS.Binding.as() que permitirá que o elemento na página seja modificado caso o model sofra alterações. Para maiores detalhes sobre binding, acesse “Guia de início rápido: associando dados e estilos”.

  4. Agora, dentro de “ready` vamos adicionar o seguinte trecho de código:
        ready: function (element, options) {
            // Retrieve the button and register our event handler. 
            var helloButton = document.getElementById("helloButton");
            helloButton.addEventListener("click", helloButtonClickHandler, false);
        }
    	

    Nota:
    O ready permite definir código que será executado assim que a página tiver sido carregada. Para mais detalhes, acessar o link [“WinJS.UI.Pages.define function”](https://msdn.microsoft.com/pt-br/library/windows/apps/hh770579.aspx).

  5. Depois vamos incluir, no final do código Javascript, antes da linha com o código a linha de código })();, o seguinte trecho:
        function helloButtonClickHandler(eventInfo) {
            var userName = document.getElementById("nameInput").value;
            var greetingString = "Hello, " + userName + "!";
    
            //update the model with new information. The bind will automatically 
            //update any html content related with it
            UniversalAppSample.model.greetings = greetingString;
        }
    	

  6. Ainda está faltando apenas um detalhe. Varrer nossa UI para obter os bindings declarativos e associá-los com nosso código. Para tanto usamos e função WinJS.Binding.processAll(). Vamos adicionar a seguinte linha de código no final da função associada ao evento ready (linha em destaque):

        ready: function (element, options) {
            // Retrieve the button and register our event handler. 
            var helloButton = document.getElementById("helloButton");
            helloButton.addEventListener("click", helloButtonClickHandler, false);
    
            // Process all declarative binds defined inside rootPageElement
            var rootPageElement = document.querySelector("div.homepage");
            WinJS.Binding.processAll(rootPageElement, UniversalAppSample.model);
        }
        

    Nota:
    Nós varremos a UI a partir do elemento div cuja classe é `.homepage` associando os elementos com a informação `model` contida no namespace `UniversalAppSample`. Todos os *binds* declarativos definidos no HTML serão então associados com o model.

  7. Agora vamos testar a aplicação tanto no Windows como no Windows Phone. Lembre-se que para executar cada projeto, você deve antes setar o projeto inicial para depois então executá-lo. Para tanto, selecione o projeto desejado e acesse o item de menu “PROJECT > Set as StartUp Project”.
    • Para Windows obtemos:

    • Para Windows Phone obtemos:

  8. Perceba que ao clicar o botão, é alterado o texto da nossa <div> que fica logo abaixo da caixa de texto.

Pronto, conseguimos implementar um único código (tanto HTML como Javascript) e deixá-lo funcionando nas duas plataformas alterando os arquivos contidos no projeto “Shared”.

Mas nem sempre é tão fácil. Em alguns momentos precisamos tratar casos específicos e saber lidar com as diferenças entre o Windows e Windows Phone.

Etapa 2 – Compartilhamento de Código: Isolando código específico

Até agora vimos compartilhamento de código que é aproveitado entre as duas plataformas. Mas e se precisarmos especificar um código na parte comum que seja específico para uma determinada plataforma?

Uma opção seria replicarmos o código nas duas plataformas. Como exemplo, teríamos o arquivo home.js replicado nas duas plataformas.

Porém, se seguirmos essa estratégia iremos perder muito do compartilhamento, prejudicando tanto a produtividade como o grau de manutenibilidade do nosso código.

Por outro lado podemos pensar numa alternativa mais simples. Usar os próprios recursos do HTML, CSS e Javascript para delimitarmos o código específico.

Para isso vamos usar a propriedade WinJS.Utilities.isPhone que está disponível somente para Windows Phone.

  1. Para a nossa Universal App criada no post anterior, vamos criar uma cópia do arquivo Shared\pages\home\home.html em cada um dos projetos: em Windows\pages\home\home.html e WindowsPhone\pages\home\home.html. Depois, vamos remover este arquivo do projeto “Shared”.

    Este tipo de modificação as vezes é necessária quando notamos que uma página que inicialmente é compartilhada entre as plataformas começa a ficar bem diferente de uma plataforma para outra. Nesse caso, talvez o o ideal seja mesmo partirmos para a separação entre Windows e Windows Phone.

  2. Para o arquivo Windows\pages\home\home.html, vamos incluir o componente Rating que é específico para Windows logo antes de fechar a tag </section>:

    	<label for="ratingControlDiv">
            Rate this greeting:
        </label>
        <div id="ratingControlDiv" data-win-control="WinJS.UI.Rating">
        </div>
        <div id="ratingOutput" data-win-bind="textContent: rating"></div>
    	

    Nota: Este código irá incluir um componenté de Rating na nossa página. Este controle WinJS.UI.Rating só existe para Windows. Como agora temos um home.html só pra Windows, basta especificarmos esse conteúdo somente no arquivo dessa plataforma.

  3. Agora precisamos alterar o código comum Shared\pages\home\home.js para incluirmos a lógica específica para Windows.

  4. Vamos incluir o tratamento do código referente ao Rating e que é específico para Windows logo após a definição do evento do botão helloButton:

    	if (!WinJS.Utilities.isPhone) {
            // Add new information on model that is Windows specific
    		UniversalAppSample.model.addProperty("rating", "0");
    		
    		// Retrieve the div that hosts the Rating control.
            var ratingControlDiv = document.getElementById("ratingControlDiv");
    
            // Retrieve the actual Rating control.
            var ratingControl = ratingControlDiv.winControl;
    
            // Register the event handler. 
            ratingControl.addEventListener("change", ratingChanged, false);
        }
    	

    Nota: Na linha em destaque, usamos a propriedade WinJS.Utilities.isPhone que retorna true somente se o código estiver sendo executado pelo **Windows Phone**.

  5. Já no fim do arquivo, antes da linha })();, vamos incluir a função ratingChanged que irá manipular o evento de mudança do Rating:
        function ratingChanged(eventInfo) {
            var ratingOutput = document.getElementById("ratingOutput");
            UniversalAppSample.model.rating = eventInfo.detail.tentativeRating;
        }
    	

  6. Agora vamos testar nosso código. Vamos definir o projeto Windows como sendo o projeto inicial e então executar local. Como resultado devemos obter:

Resumindo esta etapa

Quando tivermos algum código que seja específico para uma plataforma devemos verificar a propriedade WinJS.Utilities.isPhone da seguinte forma:

if (WinJS.Utilities.isPhone) {
    // Phone specific code
}
else {
    // windows specific code
}

O que vem pela frente

Neste post abordamos como lidar com compartilhamento de código Javascript entre os projetos Windows e Windows Phone considerando o cenário em que parte do código é específico para uma plataforma ou para outra.

Existem casos em que temos uma interface HTML comum que pode ser especificada no projeto Shared. Porém, conforme vimos no decorrer do post, podemos ter casos onde é necessário especificar esse HTML nos projetos específicos ao invés do projeto “Shared”.

Já no próximo post iremos focar no compartilhamento de interface e veremos como podemos definir, de forma simples, conteúdo comum de uma plataforma ou outra num arquivo HTML comum. Dessa forma, para nosso exemplo poderemos manter ainda no projeto “Shared” a nossa página home.html.

E não deixem de dar comentários e sugestões. Dessa forma podemos aperfeiçoar ainda mais o conteúdo que estamos disponibilizando aqui.

Obrigado e continue nos seguindo no talkitbr!

Anúncios