Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
pela equipa Web Camps
Descarregar o Kit de Treino Web Camps
Este laboratório prático mostra-lhe como construir uma Aplicação de Página Única (SPA) com ASP.NET Web API e Angular.js para ASP.NET 4.x.
Neste laboratório prático, irá aproveitar essas tecnologias para implementar o Geek Quiz, um site de perguntas e respostas baseado no conceito SPA. Primeiro, irá implementar a camada de serviço com ASP.NET API Web para expor os endpoints necessários para recuperar as perguntas do questionário e armazenar as respostas. Depois, vais construir uma interface rica e responsiva usando efeitos de transformação em AngularJS e CSS3.
Nas aplicações web tradicionais, o cliente (navegador) inicia a comunicação com o servidor solicitando uma página. O servidor processa então o pedido e envia o HTML da página para o cliente. Em interações subsequentes com a página – por exemplo, o utilizador navega até um link ou submete um formulário com dados – é enviado um novo pedido ao servidor, e o fluxo recomeça: o servidor processa o pedido e envia uma nova página para o navegador em resposta à nova ação solicitada pelo cliente.
Em Aplicações Single-Page (SPAs), toda a página é carregada no navegador após o pedido inicial, mas as interações subsequentes ocorrem através de requisições Ajax. Isto significa que o navegador tem de atualizar apenas a parte da página que mudou; Não é necessário recarregar toda a página. A abordagem SPA reduz o tempo que a aplicação demora a responder às ações do utilizador, resultando numa experiência mais fluida.
A arquitetura de um SPA envolve certos desafios que não existem nas aplicações web tradicionais. No entanto, tecnologias emergentes como ASP.NET Web API, frameworks JavaScript como o AngularJS e novas funcionalidades de estilo fornecidas pelo CSS3 tornam muito fácil o design e construção de SPAs.
Todo o código de exemplo e excertos estão incluídos no Kit de Formação dos Web Camps, disponível em https://aka.ms/webcamps-training-kit.
Descrição geral
Objetivos
Neste laboratório prático, vai aprender como:
- Criar um serviço ASP.NET Web API para enviar e receber dados JSON
- Crie uma interface responsiva usando AngularJS
- Melhore a experiência da interface com transformações em CSS3
Pré-requisitos
O seguinte é necessário para completar este laboratório prático:
- Visual Studio Express 2013 para Web ou superior
Configuração
Para realizar os exercícios neste laboratório prático, terá de preparar primeiro o seu ambiente.
- Abra o Explorador do Windows e navegue até à pasta Source do laboratório.
- Clique com o botão direito em Setup.cmd e selecione Executar como administrador para iniciar o processo de configuração que irá configurar o seu ambiente e instalar os excertos de código do Visual Studio para este laboratório.
- Se aparecer a caixa de diálogo Controlo da Conta de Utilizador, confirme a ação para prosseguir.
Observação
Certifica-te de que verificaste todas as dependências deste laboratório antes de executares a configuração.
Utilização de Fragmentos de Código
Ao longo do documento do laboratório, ser-se-á instruído a inserir blocos de código. Para sua conveniência, a maior parte deste código é fornecida como Excertos de Código do Visual Studio, aos quais pode aceder dentro do Visual Studio 2013 para evitar ter de o adicionar manualmente.
Observação
Cada exercício é acompanhado por uma solução inicial localizada na pasta Begin do exercício, que permite seguir cada exercício independentemente dos outros. Por favor, tenha em atenção que os excertos de código adicionados durante um exercício estão em falta nestas soluções iniciais e podem não funcionar até completar o exercício. Dentro do código-fonte de um exercício, encontrará também uma pasta End contendo uma solução Visual Studio com o código resultante da conclusão dos passos do exercício correspondente. Pode usar estas soluções como orientação caso precise de ajuda adicional durante este laboratório prático.
Exercícios
Este laboratório prático inclui os seguintes exercícios:
Tempo estimado para completar este laboratório: 60 minutos
Observação
Quando iniciar o Visual Studio pela primeira vez, deve selecionar uma das coleções de definições pré-definidas. Cada coleção pré-definida é concebida para corresponder a um estilo de desenvolvimento particular e determina layouts de janelas, comportamento do editor, excertos de código IntelliSense e opções de caixas de diálogo. Os procedimentos deste laboratório descrevem as ações necessárias para realizar uma determinada tarefa no Visual Studio ao utilizar a coleção General Development Settings . Se escolher uma coleção de definições diferente para o seu ambiente de desenvolvimento, pode haver diferenças nos passos que deve considerar.
Exercício 1: Criação de uma API Web
Uma das partes-chave de um SPA é a camada de serviço. É responsável por processar as chamadas Ajax enviadas pela interface e por devolver os dados em resposta a essa chamada. Os dados recuperados devem ser apresentados num formato legível por máquina para serem analisados e consumidos pelo cliente.
A framework Web API faz parte da ASP.NET Stack e foi concebida para facilitar a implementação de serviços HTTP, geralmente enviando e recebendo dados em formato JSON ou XML através de uma API RESTful. Neste exercício, irá criar o site para alojar a aplicação Geek Quiz e depois implementar o serviço de back-end para expor e persistir os dados do questionário usando ASP.NET Web API.
Tarefa 1 – Criar o Projeto Inicial para o Geek Quiz
Nesta tarefa, começará a criar um novo projeto ASP.NET MVC com suporte para ASP.NET Web API, baseado no tipo de projeto One ASP.NET que vem com o Visual Studio. Um ASP.NET unifica todas as tecnologias ASP.NET e dá-te a opção de as misturar e combinar conforme desejar. Depois adicionará as classes modelo do Entity Framework e o inicializador da base de dados para inserir as perguntas do questionário.
Abra o Visual Studio Express 2013 para Web e selecione Ficheiro | Novo projeto... para começar uma nova solução.
Criar um Novo Projeto
Na caixa de diálogo Novo Projeto , selecione Aplicação Web ASP.NET no Separador Visual C# | Web. Certifique-se de que está selecionado o .NET Framework 4.5, nomeie-o como GeekQuiz, escolha uma Localização e clique em OK.
Criar um novo projeto de Aplicação Web ASP.NET
Na caixa de diálogo do Projeto Novo ASP.NET , selecione o modelo MVC e selecione a opção Web API . Além disso, certifique-se de que a opção de Autenticação está definida como Contas de Utilizador Individuais. Clique em OK para continuar.
Criar um novo projeto com o modelo MVC, incluindo componentes Web API
No Explorador de Soluções, clique com o botão direito na pasta Modelos do projeto GeekQuiz e selecione Adicionar | Item Existente....
Adicionar um item existente
Na caixa de diálogo Adicionar Item Existente , navegue até à pasta Source/Assets/Models e selecione todos os ficheiros. Clique em Adicionar.
Adição dos recursos do modelo
Observação
Ao adicionar estes ficheiros, está a adicionar o modelo de dados, o contexto da base de dados do Entity Framework e o inicializador da base de dados para a aplicação Geek Quiz.
Entity Framework (EF) é um mapeador objeto-relacional (ORM) que permite criar aplicações de acesso a dados programando com um modelo conceptual de aplicação, em vez de programar diretamente usando um esquema de armazenamento relacional. Pode saber mais sobre o Entity Framework aqui.
Segue-se uma descrição das aulas que acabou de adicionar:
- TriviaOption: representa uma única opção associada a uma pergunta de quiz
- TriviaPergunta: representa uma pergunta de quiz e expõe as opções associadas através da propriedade Opções
- TriviaResposta: representa a opção selecionada pelo utilizador em resposta a uma pergunta de questionário
- TriviaContext: representa o contexto da base de dados do Entity Framework da aplicação Geek Quiz. Esta classe deriva do DContext e expõe propriedades do DbSet que representam coleções das entidades descritas acima.
- TriviaDatabaseInitializer: a implementação do inicializador Entity Framework para a classe TriviaContext , que herda de CreateDatabaseIfNotExists. O comportamento padrão desta classe é criar a base de dados apenas se esta não existir, inserindo as entidades especificadas no método Seed .
Abra o ficheiro Global.asax.cs e adicione a seguinte instrução usando .
using GeekQuiz.Models;Adicione o seguinte código no início do método Application_Start para definir o TriviaDatabaseInitializer como inicializador da base de dados.
public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { System.Data.Entity.Database.SetInitializer(new TriviaDatabaseInitializer()); AreaRegistration.RegisterAllAreas(); GlobalConfiguration.Configure(WebApiConfig.Register); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); } }Modificar o controlador Home para restringir o acesso a utilizadores autenticados. Para isso, abra o ficheiro HomeController.cs dentro da pasta Controllers e adicione o atributo Authorize à definição da classe HomeController .
namespace GeekQuiz.Controllers { [Authorize] public class HomeController : Controller { public ActionResult Index() { return View(); } ... } }Observação
O filtro Autorizar verifica se o utilizador está autenticado. Se o utilizador não estiver autenticado, devolve o código de estado HTTP 401 (Não autorizado) sem invocar a ação. Pode aplicar o filtro globalmente, ao nível do controlador ou ao nível das ações individuais.
Agora irá personalizar o layout das páginas web e a imagem da marca. Para isso, abra o ficheiro _Layout.cshtml dentro da pasta Views | Shared e atualize o conteúdo do <title> substituindo a Minha Aplicação ASP.NET por Geek Quiz.
<head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>@ViewBag.Title - Geek Quiz</title> @Styles.Render("~/Content/css") @Scripts.Render("~/bundles/modernizr") </head>No mesmo ficheiro, atualize a barra de navegação removendo os links Sobre e Contacto e renomeando o link Home para Play. Além disso, renomeie o link do nome da Aplicação para Geek Quiz. O HTML da barra de navegação deve assemelhar-se ao seguinte código.
<div class="navbar navbar-inverse navbar-fixed-top"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> @Html.ActionLink("Geek Quiz", "Index", "Home", null, new { @class = "navbar-brand" }) </div> <div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li>@Html.ActionLink("Play", "Index", "Home")</li> </ul> @Html.Partial("_LoginPartial") </div> </div> </div>Atualize o rodapé da página de layout substituindo Minha Aplicação ASP.NET por Geek Quiz. Para isso, substitua o conteúdo do <elemento de> rodapé pelo código destacado a seguir.
<div class="container body-content"> @RenderBody() <hr /> <footer> <p>© @DateTime.Now.Year - Geek Quiz</p> </footer> </div>
Tarefa 2 – Criar a API Web do TriviaController
Na tarefa anterior, criou a estrutura inicial da aplicação web Geek Quiz. Agora irá construir um serviço simples de API Web que interage com o modelo de dados do questionário e expõe as seguintes ações:
- GET /api/trivia: Recupera a próxima pergunta da lista de questionários para ser respondida pelo utilizador autenticado.
- POST /api/trivia: Armazena a resposta do questionário especificada pelo utilizador autenticado.
Irá utilizar as ferramentas ASP.NET Scaffolding fornecidas pelo Visual Studio para criar a base para a classe controlador da Web API.
Abre o ficheiro WebApiConfig.cs dentro da pasta App_Start . Este ficheiro define a configuração do serviço Web API, tal como as rotas são mapeadas para as ações do controlador Web API.
Adicione a seguinte instrução "using" no início do ficheiro.
using Newtonsoft.Json.Serialization;Adicione o seguinte código destacado ao método Register para configurar globalmente o formatador dos dados JSON recuperados pelos métodos de ação da Web API.
public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API configuration and services // Use camel case for JSON data. config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); // Web API routes config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); } }Observação
O CamelCasePropertyNamesContractResolver converte automaticamente nomes de propriedades para camel case, que é a convenção geral para nomes de propriedades em JavaScript.
No Explorador de Soluções, clique com o botão direito na pasta Controladores do projeto GeekQuiz e selecione Adicionar | Novo Item Andaimado....
Criação de um novo item com andaimes
Na caixa de diálogo Adicionar Andaime, certifique-se de que o nó Comum está selecionado no painel esquerdo. Depois, selecione o modelo Web API 2 Controller - Vazio no painel central e clique em Adicionar.
Selecionar o modelo vazio do controlador Web API 2
Observação
ASP.NET Scaffolding é uma estrutura de geração de código para ASP.NET aplicações Web. O Visual Studio 2013 inclui geradores de código pré-instalados para projetos MVC e Web API. Deve usar andaimes no seu projeto quando quiser adicionar rapidamente código que interaja com modelos de dados para reduzir o tempo necessário para desenvolver operações padrão de dados.
O processo de andaime também garante que todas as dependências necessárias são instaladas no projeto. Por exemplo, se começar com um projeto de ASP.NET vazio e depois usar andaimes para adicionar um controlador da Web API, os pacotes e referências NuGet da Web API necessários são automaticamente adicionados ao seu projeto.
Na caixa de diálogo Adicionar Controlador , escreva TriviaController na caixa de texto do nome do Controlador e clique em Adicionar.
Adição do Controlador de Perguntas
O ficheiro TriviaController.cs é então adicionado à pasta Controllers do projeto GeekQuiz , contendo uma classe TriviaController vazia. Adicione as seguintes diretivas de uso no início do ficheiro.
(Excerto de Código - AspNetWebApiSpa - Ex1 - TriviaControllerUsings)
using System.Data.Entity; using System.Threading; using System.Threading.Tasks; using System.Web.Http.Description; using GeekQuiz.Models;Adicione o seguinte código no início da classe TriviaController para definir, inicializar e eliminar a instância TriviaContext no controlador.
(Excerto de Código - AspNetWebApiSpa - Ex1 - TriviaControllerContext)
public class TriviaController : ApiController { private TriviaContext db = new TriviaContext(); protected override void Dispose(bool disposing) { if (disposing) { this.db.Dispose(); } base.Dispose(disposing); } }Observação
O método Dispose do TriviaController invoca o método Dispose da instância TriviaContext , que garante que todos os recursos usados pelo objeto de contexto são libertados quando a instância do TriviaContext é descartada ou recolhida no lixo. Isto inclui o encerramento de todas as ligações à base de dados abertas pelo Entity Framework.
Adicione o seguinte método auxiliar no final da classe TriviaControler . Este método recupera a seguinte pergunta do quiz da base de dados para ser respondida pelo utilizador especificado.
(Excerto de Código - AspNetWebApiSpa - Ex1 - TriviaControllerNextQuestion)
private async Task<TriviaQuestion> NextQuestionAsync(string userId) { var lastQuestionId = await this.db.TriviaAnswers .Where(a => a.UserId == userId) .GroupBy(a => a.QuestionId) .Select(g => new { QuestionId = g.Key, Count = g.Count() }) .OrderByDescending(q => new { q.Count, QuestionId = q.QuestionId }) .Select(q => q.QuestionId) .FirstOrDefaultAsync(); var questionsCount = await this.db.TriviaQuestions.CountAsync(); var nextQuestionId = (lastQuestionId % questionsCount) + 1; return await this.db.TriviaQuestions.FindAsync(CancellationToken.None, nextQuestionId); }Adicione o seguinte método de ação Get à classe TriviaControler . Este método de ação chama o método helper NextQuestionAsync definido no passo anterior para recuperar a próxima pergunta para o utilizador autenticado.
(Excerto de Código - AspNetWebApiSpa - Ex1 - TriviaControllerGetAction)
// GET api/Trivia [ResponseType(typeof(TriviaQuestion))] public async Task<IHttpActionResult> Get() { var userId = User.Identity.Name; TriviaQuestion nextQuestion = await this.NextQuestionAsync(userId); if (nextQuestion == null) { return this.NotFound(); } return this.Ok(nextQuestion); }Adicione o seguinte método auxiliar no final da classe TriviaControler . Este método armazena a resposta especificada na base de dados e devolve um valor booleano indicando se a resposta está correta ou não.
(Excerto de Código - AspNetWebApiSpa - Ex1 - TriviaControllerStoreAsync)
private async Task<bool> StoreAsync(TriviaAnswer answer) { this.db.TriviaAnswers.Add(answer); await this.db.SaveChangesAsync(); var selectedOption = await this.db.TriviaOptions.FirstOrDefaultAsync(o => o.Id == answer.OptionId && o.QuestionId == answer.QuestionId); return selectedOption.IsCorrect; }Adicione o seguinte método Post action à classe TriviaControler . Este método de ação associa a resposta ao utilizador autenticado e chama o método helper StoreAsync . Depois, envia uma resposta com o valor booleano devolvido pelo método auxiliar.
(Excerto de Código - AspNetWebApiSpa - Ex1 - TriviaControllerPostAction)
// POST api/Trivia [ResponseType(typeof(TriviaAnswer))] public async Task<IHttpActionResult> Post(TriviaAnswer answer) { if (!ModelState.IsValid) { return this.BadRequest(this.ModelState); } answer.UserId = User.Identity.Name; var isCorrect = await this.StoreAsync(answer); return this.Ok<bool>(isCorrect); }Modificar o controlador Web API para restringir o acesso a utilizadores autenticados, adicionando o atributo Authorize à definição da classe TriviaControler .
[Authorize] public class TriviaController : ApiController { ... }
Tarefa 3 – Executar a Solução
Nesta tarefa, irá verificar se o serviço Web API que construiu na tarefa anterior está a funcionar como esperado. Utilizará as Ferramentas de Desenvolvimento do Internet Explorer F12 para captar o tráfego de rede e inspecionar a resposta completa do serviço Web API.
Observação
Certifique-se de que o Internet Explorer está selecionado no botão Iniciar localizado na barra de ferramentas do Visual Studio.
Pressiona F5 para executar a solução. A página de Início de Sessão deve aparecer no navegador.
Observação
Quando a aplicação inicia, a rota padrão do MVC é ativada, sendo mapeada por padrão para a ação Index da classe HomeControlador. Como o HomeController está restrito a utilizadores autenticados (lembre-se que decorou essa classe com o atributo Authorize no Exercício 1) e ainda não há utilizador autenticado, a aplicação redireciona o pedido original para a página de login.
Execução da solução
Clique em Registar para criar um novo utilizador.
Registar um novo utilizador
Na página de Registo , introduza um Nome de Utilizador e uma Palavra-passe, e depois clique em Registar.
Página de registo
A aplicação regista a nova conta e o utilizador é autenticado e redirecionado de volta para a página inicial.
O utilizador é autenticado
No navegador, pressione F12 para abrir o painel de Ferramentas para Desenvolvedores . Pressione CTRL + 4 ou clique no ícone de rede , e depois clique no botão de seta verde para começar a captar o tráfego de rede.
Iniciar a captura de redes Web API
Adicione API/curiosidades à URL na barra de endereços do navegador. Agora irá inspecionar os detalhes da resposta do método de ação Get no TriviaController.
Recuperação dos dados da próxima pergunta através da Web API
Observação
Quando o download terminar, ser-se-á solicitado a fazer uma ação com o ficheiro descarregado. Deixa a caixa de diálogo aberta para poderes ver o conteúdo das respostas através da janela da Ferramenta de Desenvolvedores.
Agora inspecionará o conteúdo da resposta. Para isso, clique no separador Detalhes e depois em Corpo da Resposta. Pode verificar se os dados descarregados são um objeto com as opções de propriedades (que é uma lista de objetos TriviaOption ), id e título que correspondem à classe TriviaQuestion .
Visualização do Corpo de Resposta da Web API
Volte ao Visual Studio e pressione SHIFT + F5 para encerrar a depuração.
Exercício 2: Criação da Interface SPA
Neste exercício, vai primeiro construir a parte front-end web do Geek Quiz, focando-se na interação de aplicação de página única usando AngularJS. Depois, irá melhorar a experiência do utilizador com o CSS3 para realizar animações ricas e proporcionar um efeito visual de mudança de contexto ao transitar de uma pergunta para a seguinte.
Tarefa 1 – Criar a Interface SPA Usando AngularJS
Nesta tarefa vais usar o AngularJS para implementar o lado do cliente da aplicação Geek Quiz. AngularJS é uma framework JavaScript de código aberto que complementa aplicações baseadas em navegador com capacidade Model-View-Controller (MVC), facilitando tanto o desenvolvimento como os testes.
Vai começar por instalar o AngularJS a partir da Console do Gestor de Pacotes do Visual Studio. Depois, irá criar o controlador para fornecer o comportamento da aplicação Geek Quiz e a vista para renderizar as perguntas e respostas do quiz usando o motor de templates AngularJS.
Observação
Para mais informações sobre o AngularJS, consulte [http://angularjs.org/](http://angularjs.org/).
Abra o Visual Studio Express 2013 para Web e abra a solução GeekQuiz.sln localizada na pasta Source/Ex2-CreatingASPAInterface/Begin . Em alternativa, pode continuar com a solução que obteve no exercício anterior.
Abra a Consola do Gestor de Pacotes a partir de Ferramentas>Gestor de Pacotes NuGet. Escreva o seguinte comando para instalar o pacote NuGet AngularJS.Core .
Install-Package AngularJS.CoreNo Explorador de Soluções, clique com o botão direito na pasta Scripts do projeto GeekQuiz e selecione Adicionar | Nova Pasta. Nomeie a pasta app e prima Enter.
Clique com o botão direito na pasta da aplicação que acabou de criar e selecione Adicionar | Ficheiro JavaScript.
Criação de um novo ficheiro JavaScript
Na caixa de diálogo Especificar Nome para Item , escreva quiz-controller na caixa de texto Nome do Item e clique em OK.
Nomeação do novo ficheiro JavaScript
No ficheiroquiz-controller.js , adicione o seguinte código para declarar e inicializar o controlador AngularJS QuizCtrl .
(Excerto de Código - AspNetWebApiSpa - Ex2 - AngularQuizController)
angular.module('QuizApp', []) .controller('QuizCtrl', function ($scope, $http) { $scope.answered = false; $scope.title = "loading question..."; $scope.options = []; $scope.correctAnswer = false; $scope.working = false; $scope.answer = function () { return $scope.correctAnswer ? 'correct' : 'incorrect'; }; });Observação
A função construtora do controlador QuizCtrl espera um parâmetro injetável chamado $scope. O estado inicial do âmbito deve ser configurado na função construtora anexando propriedades ao objeto $scope . As propriedades contêm o modelo de vista e estarão acessíveis ao template quando o controlador estiver registado.
O controlador QuizCtrl é definido dentro de um módulo chamado QuizApp. Os módulos são unidades de trabalho que permitem dividir a tua aplicação em componentes separados. As principais vantagens de usar módulos são que o código é mais fácil de compreender e facilita os testes unitários, a reutilização e a manutenção.
Agora irá adicionar comportamento ao âmbito para reagir a eventos desencadeados pela vista. Adicione o código seguinte no final do controlador QuizCtrl para definir a função nextQuestion no objeto $scope .
(Excerto de Código - AspNetWebApiSpa - Ex2 - AngularQuizControllerNextQuestion)
.controller('QuizCtrl', function ($scope, $http) { ... $scope.nextQuestion = function () { $scope.working = true; $scope.answered = false; $scope.title = "loading question..."; $scope.options = []; $http.get("/api/trivia").success(function (data, status, headers, config) { $scope.options = data.options; $scope.title = data.title; $scope.answered = false; $scope.working = false; }).error(function (data, status, headers, config) { $scope.title = "Oops... something went wrong"; $scope.working = false; }); }; };Observação
Esta função recupera a próxima pergunta da Trivia Web API criada no exercício anterior e anexa os dados da pergunta ao objeto $scope .
Insira o seguinte código no final do controlador QuizCtrl para definir a função sendAnswer no objeto $scope .
(Excerto de Código - AspNetWebApiSpa - Ex2 - AngularQuizControllerSendAnswer)
.controller('QuizCtrl', function ($scope, $http) { ... $scope.sendAnswer = function (option) { $scope.working = true; $scope.answered = true; $http.post('/api/trivia', { 'questionId': option.questionId, 'optionId': option.id }).success(function (data, status, headers, config) { $scope.correctAnswer = (data === true); $scope.working = false; }).error(function (data, status, headers, config) { $scope.title = "Oops... something went wrong"; $scope.working = false; }); }; };Observação
Esta função envia a resposta selecionada pelo utilizador para a API Web do Trivia e armazena o resultado – ou seja, se a resposta está correta ou não – no objeto $scope .
As funções nextQuestion e sendAnswer indicadas acima usam o objeto $http do AngularJS para abstrair a comunicação com a Web API através do objeto JavaScript XMLHttpRequest do navegador da web. O AngularJS suporta outro serviço que traz um nível superior de abstração para realizar operações CRUD contra um recurso através de APIs RESTful. O objeto $resource AngularJS tem métodos de ação que fornecem comportamentos de alto nível sem necessidade de interagir com o objeto $http . Considere usar o objeto $resource em cenários que requerem o modelo CRUD (para mais informações, veja a documentação $resource).
O passo seguinte é criar o modelo AngularJS que define a vista para o questionário. Para isso, abra o ficheiro Index.cshtml dentro do Views | A pasta Home e substitui o conteúdo pelo seguinte código.
(Excerto de Código - AspNetWebApiSpa - Ex2 - GeekQuizView)
@{ ViewBag.Title = "Play"; } <div id="bodyContainer" ng-app="QuizApp"> <section id="content"> <div class="container" > <div class="row"> <div class="flip-container text-center col-md-12" ng-controller="QuizCtrl" ng-init="nextQuestion()"> <div class="back" ng-class="{flip: answered, correct: correctAnswer, incorrect:!correctAnswer}"> <p class="lead">{{answer()}}</p> <p> <button class="btn btn-info btn-lg next option" ng-click="nextQuestion()" ng-disabled="working">Next Question</button> </p> </div> <div class="front" ng-class="{flip: answered}"> <p class="lead">{{title}}</p> <div class="row text-center"> <button class="btn btn-info btn-lg option" ng-repeat="option in options" ng-click="sendAnswer(option)" ng-disabled="working">{{option.title}}</button> </div> </div> </div> </div> </div> </section> </div> @section scripts { @Scripts.Render("~/Scripts/angular.js") @Scripts.Render("~/Scripts/app/quiz-controller.js") }Observação
O template AngularJS é uma especificação declarativa que utiliza informação do modelo e do controlador para transformar a marcação estática na vista dinâmica que o utilizador vê no navegador. Seguem-se exemplos de elementos e atributos de elementos AngularJS que podem ser usados num template:
- A diretiva ng-app indica ao AngularJS o elemento DOM que representa o elemento raiz da aplicação.
- A diretiva ng-controller associa um controlador ao DOM no ponto onde a diretiva é declarada.
- A notação de colchetes curly {{ }} denota ligações às propriedades do âmbito definidas no controlador.
- A diretiva ng-click é usada para invocar as funções definidas no âmbito em resposta a cliques do utilizador.
Abra o ficheiro Site.css dentro da pasta Conteúdo e adicione os seguintes estilos destacados no final do ficheiro para dar uma visão visual e sensacional para a vista do questionário.
(Excerto de Código - AspNetWebApiSpa - Ex2 - GeekQuizStyles)
.validation-summary-valid { display: none; } /* Geek Quiz styles */ .flip-container .back, .flip-container .front { border: 5px solid #00bcf2; padding-bottom: 30px; padding-top: 30px; } #content { position:relative; background:#fff; padding:50px 0 0 0; } .option { width:140px; margin: 5px; } div.correct p { color: green; } div.incorrect p { color: red; } .btn { border-radius: 0; } .flip-container div.front, .flip-container div.back.flip { display: block; } .flip-container div.front.flip, .flip-container div.back { display: none; }
Tarefa 2 – Executar a Solução
Nesta tarefa, vais executar a solução usando a nova interface de utilizador que criaste com o AngularJS para responder a algumas das perguntas do questionário.
Pressiona F5 para executar a solução.
Regista uma nova conta de utilizador. Para tal, siga os passos de registo descritos no Exercício 1, Tarefa 3.
Observação
Se estiver a usar a solução do exercício anterior, pode iniciar sessão com a conta de utilizador que criou anteriormente.
Deverá aparecer a página inicial , mostrando a primeira pergunta do questionário. Responda à pergunta clicando numa das opções. Isto irá ativar a função sendAnswer definida anteriormente, que envia a opção selecionada para a API Web do Trivia .
Responder a uma pergunta
Depois de clicar num dos botões, a resposta deverá aparecer. Clique em Próxima Pergunta para mostrar a seguinte pergunta. Isto vai ativar a função nextQuestion definida no controlador.
Solicitar a próxima pergunta
A próxima pergunta deve aparecer. Continua a responder às perguntas quantas vezes quiseres. Depois de completares todas as perguntas, deves voltar à primeira pergunta.
Próxima pergunta
Volte ao Visual Studio e pressione SHIFT + F5 para encerrar a depuração.
Tarefa 3 – Criar uma Animação de Flip usando CSS3
Nesta tarefa vais usar as propriedades do CSS3 para realizar animações ricas, adicionando um efeito de flip quando uma pergunta é respondida e quando a próxima pergunta for recuperada.
No Explorador de Soluções, clique com o botão direito na pasta Conteúdo do projeto GeekQuiz e selecione Adicionar | Item Existente....
Adicionar um item existente à pasta Content
Na caixa de diálogo Adicionar Item Existente , navegue até à pasta Source/Assets e selecione Flip.css. Clique em Adicionar.
Adicionar o ficheiro Flip.css a partir de Assets
Abre o ficheiro Flip.css que acabaste de adicionar e inspeciona o seu conteúdo.
Localiza o comentário sobre a transformação de espelhamento. Os estilos abaixo desse comentário usam as transformações CSS perspetiva e rotateY para gerar um efeito de "virar cartão".
/* flip transformation */ .flip-container div.front { -moz-transform: perspective(2000px) rotateY(0deg); -webkit-transform: perspective(2000px) rotateY(0deg); -o-transform: perspective(2000px) rotateY(0deg); transform: perspective(2000px) rotateY(0deg); } .flip-container div.front.flip { -moz-transform: perspective(2000px) rotateY(179.9deg); -webkit-transform: perspective(2000px) rotateY(179.9deg); -o-transform: perspective(2000px) rotateY(179.9deg); transform: perspective(2000px) rotateY(179.9deg); } .flip-container div.back { -moz-transform: perspective(2000px) rotateY(-180deg); -webkit-transform: perspective(2000px) rotateY(-180deg); -o-transform: perspective(2000px) rotateY(-180deg); transform: perspective(2000px) rotateY(-180deg); } .flip-container div.back.flip { -moz-transform: perspective(2000px) rotateY(0deg); -webkit-transform: perspective(2000px) rotateY(0deg); -ms-transform: perspective(2000px) rotateY(0); -o-transform: perspective(2000px) rotateY(0); transform: perspective(2000px) rotateY(0); }Localiza o comentário ocultar a parte de trás do painel durante a inversão. O estilo abaixo desse comentário esconde o lado de trás das faces quando estão viradas para longe do observador, definindo a propriedade CSS backface-visibility como hidden.
/* hide back of pane during flip */ .front, .back { -moz-backface-visibility: hidden; -webkit-backface-visibility: hidden; backface-visibility: hidden; }Abra o ficheiro BundleConfig.cs dentro da pasta App_Start e adicione a referência ao ficheiro Flip.css no conjunto de estilo "~/Content/css"
bundles.Add(new StyleBundle("~/Content/css").Include( "~/Content/bootstrap.css", "~/Content/site.css", "~/Content/Flip.css"));Carrega em F5 para correr a solução e faz login com as tuas credenciais.
Responda a uma pergunta clicando numa das opções. Repara no efeito de inversão ao transitar entre vistas.
Responder a uma pergunta com o efeito flip
Clique em Próxima Pergunta para obter a seguinte pergunta. O efeito de inversão deve voltar a aparecer.
A recuperar a pergunta seguinte com o efeito de flip
Resumo
Ao completar este laboratório prático, aprendeu como:
- Crie um controlador ASP.NET Web API usando ASP.NET Scaffolding
- Implemente uma API Web Obtenha ação para recuperar a próxima pergunta do questionário
- Implemente uma ação de Post da Web API para armazenar as respostas do questionário
- Instale o AngularJS a partir da Consola do Gestor de Pacotes do Visual Studio
- Implementar templates e controladores AngularJS
- Use transições CSS3 para realizar efeitos de animação