Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Скачать набор учебных материалов Web Camps
В этой лаборатории показано, как создать одностраничные приложения (SPA) с помощью веб-API ASP.NET и Angular.js для ASP.NET 4.x.
В этой лаборатории вы будете использовать эти технологии для реализации Geek Quiz, тривиа веб-сайта на основе концепции SPA. Сначала вы реализуете уровень служб с ASP.NET веб-API для предоставления необходимых конечных точек для получения вопросов теста и хранения ответов. Затем вы создадите широкий и адаптивный пользовательский интерфейс с помощью эффектов преобразования AngularJS и CSS3.
В традиционных веб-приложениях клиент (браузер) инициирует взаимодействие с сервером, запрашивая страницу. Затем сервер обрабатывает запрос и отправляет HTML-код страницы клиенту. В последующих взаимодействиях со страницей ( например, пользователь переходит по ссылке или отправляет форму с данными— новый запрос отправляется на сервер, и поток начинается снова: сервер обрабатывает запрос и отправляет новую страницу в браузер в ответ на новое действие, запрошенное клиентом.
В одностраничных приложениях (SPAs) вся страница загружается в браузере после первоначального запроса, но последующие взаимодействия осуществляются через Ajax-запросы. Это означает, что браузер должен обновить только часть страницы, которая изменилась; Перезагрузка всей страницы не требуется. Подход SPA сокращает время, затраченное приложением на реагирование на действия пользователя, что приводит к более гибкому интерфейсу.
Архитектура SPA включает определенные проблемы, которые отсутствуют в традиционных веб-приложениях. Однако новые технологии, такие как ASP.NET веб-API, платформы JavaScript, такие как AngularJS и новые функции стилизации, предоставляемые CSS3, упрощают проектирование и сборку spAs.
Все примеры кода и фрагменты кода включены в набор для обучения веб-лагерей, доступный по адресу https://aka.ms/webcamps-training-kit.
Обзор
Цели
В этой практической лаборатории вы узнаете, как:
- Создание службы веб-API ASP.NET для отправки и получения данных JSON
- Создание адаптивного пользовательского интерфейса с помощью AngularJS
- Улучшение пользовательского интерфейса с помощью преобразований CSS3
Необходимые условия
Для выполнения этой практической работы требуется следующее:
- Visual Studio Express 2013 для Интернета или более поздней версии
Setup
Чтобы выполнить упражнения в этой практической лаборатории, необходимо сначала настроить среду.
- Откройте проводник Windows и перейдите к папке Source лаборатории.
- Щелкните правой кнопкой мыши Setup.cmd и выберите "Запуск от имени администратора ", чтобы запустить процесс установки, который настроит среду и установит фрагменты кода Visual Studio для этой лаборатории.
- Если отображается диалоговое окно "Контроль учетных записей пользователей", подтвердите действие, чтобы продолжить.
Замечание
Перед запуском установки убедитесь, что вы проверили все зависимости для этого практического задания.
Использование фрагментов кода
На протяжении всего документа лабораторной работы вам будет предложено вставлять блоки кода. Для удобства большая часть этого кода предоставляется как фрагменты кода Visual Studio Code, к которым можно получить доступ в Visual Studio 2013, чтобы избежать необходимости добавлять его вручную.
Замечание
Каждое упражнение сопровождается начальным решением, расположенным в папке "Начало " упражнения, которая позволяет выполнять каждое упражнение независимо от других. Обратите внимание, что фрагменты кода, добавленные во время упражнения, отсутствуют из этих начальных решений и могут не работать, пока не завершите упражнение. В исходном коде упражнения вы также найдете папку End , содержащую решение Visual Studio с кодом, который приводит к выполнению шагов в соответствующем упражнении. Эти решения можно использовать в качестве руководства, если вам нужна дополнительная помощь при работе с этой практической лабораторией.
Упражнения
Эта практическая лаборатория включает в себя следующие упражнения:
Предполагаемое время выполнения этого практического занятия: 60 минут
Замечание
При первом запуске Visual Studio необходимо выбрать одну из стандартных коллекций параметров. Каждая предопределенная коллекция предназначена для сопоставления определенного стиля разработки и определяет макеты окон, поведение редактора, фрагменты кода IntelliSense и параметры диалогового окна. Процедуры в этой лаборатории описывают действия, необходимые для выполнения данной задачи в Visual Studio при использовании коллекции общих параметров разработки . Если выбрать другую коллекцию параметров для среды разработки, могут возникнуть различия в действиях, которые следует учитывать.
Упражнение 1. Создание веб-API
Одним из ключевых частей SPA является уровень служб. Он отвечает за обработку вызовов Ajax, отправленных пользовательским интерфейсом, и возврат данных в ответ на этот вызов. Полученные данные должны быть представлены в формате, доступном для чтения компьютера, чтобы анализироваться и использовать их клиентом.
Платформа веб-API является частью стека ASP.NET и предназначена для упрощения реализации http-служб, как правило, отправки и получения данных в формате JSON или XML через API RESTful. В этом упражнении вы создадите веб-сайт для размещения приложения Geek Quiz, а затем реализует серверную службу для предоставления и сохранения данных теста с помощью веб-API ASP.NET.
Задача 1. Создание начального проекта для теста Geek
В этой задаче вы начнете создавать проект ASP.NET MVC с поддержкой веб-API ASP.NET на основе типа проекта One ASP.NET , который поставляется с Visual Studio. Один ASP.NET объединяет все технологии ASP.NET и предоставляет возможность смешивать и сопоставлять их по мере необходимости. Затем вы добавите классы моделей Entity Framework и инициализатор базы данных, чтобы вставить вопросы теста.
Откройте Visual Studio Express 2013 для Интернета и выберите файл | Новый проект... для запуска нового решения.
Создание проекта
В диалоговом окне "Создать проект " выберите ASP.NET веб-приложение в visual C# | Веб-вкладка . Убедитесь, что выбран .NET Framework 4.5 , назовите его GeekQuiz, выберите расположение и нажмите кнопку "ОК".
Создание проекта веб-приложения ASP.NET
В диалоговом окне "Создать ASP.NET проект" выберите шаблон MVC и выберите параметр веб-API . Кроме того, убедитесь, что для параметра проверки подлинностизадано значение "Отдельные учетные записи пользователей". Нажмите кнопку ОК, чтобы продолжить.
Создание проекта с помощью шаблона MVC, включая компоненты веб-API
В обозревателе решений щелкните правой кнопкой мыши папку "Модели " проекта GeekQuiz и выберите "Добавить |" Существующий элемент....
Добавление существующего элемента
В диалоговом окне "Добавить существующий элемент" перейдите в папку Source/Assets/Models и выберите все файлы. Нажмите кнопку Добавить.
Добавление ресурсов модели
Замечание
Добавив эти файлы, вы добавляете модель данных, контекст базы данных Entity Framework и инициализатор базы данных для приложения Geek Quiz.
Entity Framework (EF) — это объектно-реляционное отображение (ORM), которое позволяет создавать приложения для работы с данными посредством программирования с использованием концептуальной модели приложения вместо программирования непосредственно, используя реляционную схему хранения. Дополнительные сведения о Entity Framework см. здесь.
Ниже приведено описание только что добавленных классов:
- TriviaOption: представляет один вариант, связанный с вопросом теста
- TriviaQuestion: представляет вопрос теста и предоставляет связанные параметры с помощью свойства Options
- TriviaAnswer: представляет параметр, выбранный пользователем в ответ на вопрос теста
- TriviaContext: представляет контекст базы данных Entity Framework приложения Geek Quiz. Этот класс является производным от DContext и предоставляет свойства DbSet , представляющие коллекции сущностей, описанных выше.
- TriviaDatabaseInitializer: реализация инициализатора Entity Framework для класса TriviaContext , наследуемого от CreateDatabaseIfNotExists. Поведение этого класса по умолчанию заключается в создании базы данных, только если она не существует, вставляя сущности, указанные в методе Seed .
Откройте файл Global.asax.cs и добавьте следующую инструкцию using.
using GeekQuiz.Models;Добавьте следующий код в начале метода Application_Start , чтобы задать TriviaDatabaseInitializer в качестве инициализатора базы данных.
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); } }Измените контроллер дома , чтобы ограничить доступ к прошедшим проверку подлинности пользователям. Для этого откройте файл HomeController.cs в папке Controllers и добавьте атрибут Authorize в определение класса HomeController .
namespace GeekQuiz.Controllers { [Authorize] public class HomeController : Controller { public ActionResult Index() { return View(); } ... } }Замечание
Фильтр авторизации проверяет, прошел ли пользователь проверку подлинности. Если пользователь не прошел проверку подлинности, он возвращает код состояния HTTP 401 (несанкционированный) без вызова действия. Фильтр можно применять глобально, на уровне контроллера или на уровне отдельных действий.
Теперь вы настроите макет веб-страниц и фирменную символику. Для этого откройте файл _Layout.cshtml в папке Views | Shared и обновите содержимое <элемента title>, заменив My ASP.NET Application на 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>В том же файле обновите панель навигации, удалив ссылки "О " и " Контакт" и переименуя ссылку "Главная " на Play. Кроме того, переименуйте ссылку "Имя приложения " на Geek Quiz. HTML-код для панели навигации должен выглядеть следующим образом.
<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>Обновите нижний колонтитул страницы макета, заменив my ASP.NET Application на Geek Quiz. Для этого замените содержимое элемента колонтитула следующим выделенным кодом.
<div class="container body-content"> @RenderBody() <hr /> <footer> <p>© @DateTime.Now.Year - Geek Quiz</p> </footer> </div>
Задача 2. Создание веб-API TriviaController
В предыдущей задаче вы создали начальную структуру веб-приложения Geek Quiz. Теперь вы создадите простую веб-службу API, которая взаимодействует с моделью данных теста и предоставляет следующие действия:
- GET /api/trivia: извлекает следующий вопрос из списка тестов, на которые отвечает прошедший проверку подлинности пользователь.
- POST/api/trivia: сохраняет ответ теста, указанный пользователем, прошедшим проверку подлинности.
Вы будете использовать средства ASP.NET Scaffolding, предоставляемые Visual Studio, для создания основы для класса контроллера Web API.
Откройте файл WebApiConfig.cs в папке App_Start . Этот файл определяет конфигурацию службы веб-API, например способ сопоставлений маршрутов с действиями контроллера веб-API.
Добавьте следующую инструкцию using в начале файла.
using Newtonsoft.Json.Serialization;Добавьте следующий выделенный код в метод Register , чтобы глобально настроить форматировщик данных JSON, полученных методами действий веб-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 } ); } }Замечание
CamelCasePropertyNamesContractResolver автоматически преобразует имена свойств в camelCase, что является общепринятым соглашением для имен свойств в JavaScript.
В обозревателе решений щелкните правой кнопкой мыши папку "Контроллеры " проекта GeekQuiz и выберите "Добавить |" Новый шаблонный элемент....
Создание нового скелетного элемента
В диалоговом окне “Добавление каркаса” убедитесь, что в левой области выбран узел Общий. Затем выберите контроллер веб-API 2 — пустой шаблон в центральной области и нажмите кнопку "Добавить".
Выбор шаблона Empty для Web API 2 Controller
Замечание
ASP.NET шаблон — это платформа создания кода для веб-приложений ASP.NET. Visual Studio 2013 включает предварительно установленные генераторы кода для проектов MVC и веб-API. Вы должны использовать шаблон в проекте, если требуется быстро добавить код, взаимодействующий с моделями данных, чтобы сократить время, необходимое для разработки стандартных операций с данными.
Процесс формирования шаблонов также гарантирует, что все необходимые зависимости установлены в проекте. Например, если начать с пустого проекта ASP.NET и затем использовать скафолдинг для добавления контроллера Web API, необходимые пакеты NuGet и ссылки на Web API добавляются в проект автоматически.
В диалоговом окне "Добавить контроллер" введите TriviaController в текстовом поле "Имя контроллера " и нажмите кнопку "Добавить".
Добавление контроллера Trivia
Затем файл TriviaController.cs добавляется в папку Controllers проекта GeekQuiz , содержащую пустой класс TriviaController . Добавьте следующие инструкции using в начале файла.
(Фрагмент кода — AspNetWebApiSpa — Ex1 — TriviaControllerUsings)
using System.Data.Entity; using System.Threading; using System.Threading.Tasks; using System.Web.Http.Description; using GeekQuiz.Models;Добавьте следующий код в начале класса TriviaController , чтобы определить, инициализировать и удалить экземпляр TriviaContext в контроллере.
(Фрагмент кода — 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); } }Замечание
Метод Dispose метода TriviaController вызывает метод Dispose экземпляра TriviaContext, который гарантирует, что все ресурсы, используемые объектом контекста, освобождаются, когда происходит удаление или сборка мусора экземпляра TriviaContext. Это включает закрытие всех подключений к базе данных, открытых Entity Framework.
Добавьте следующий вспомогательный метод в конце класса TriviaController . Этот метод извлекает следующий вопрос викторины из базы данных, на который должен ответить указанный пользователь.
(Фрагмент кода — 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); }Добавьте следующий метод действия Get в класс TriviaController . Этот метод действия вызывает вспомогательный метод NextQuestionAsync , определенный на предыдущем шаге, чтобы получить следующий вопрос для прошедшего проверку подлинности пользователя.
(Фрагмент кода — 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); }Добавьте следующий вспомогательный метод в конце класса TriviaController . Этот метод сохраняет указанный ответ в базе данных и возвращает логическое значение, указывающее, является ли ответ правильным.
(Фрагмент кода — 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; }Добавьте следующий метод действия Post в класс TriviaController . Этот метод действия связывает ответ с прошедшим проверку подлинности пользователем и вызывает вспомогательный метод StoreAsync . Затем он отправляет ответ с булевым значением, которое возвращает вспомогательный метод.
(Фрагмент кода — 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); }Измените контроллер веб-API, чтобы ограничить доступ к прошедшим проверку подлинности пользователям, добавив атрибут Authorize в определение класса TriviaController .
[Authorize] public class TriviaController : ApiController { ... }
Задача 3. Запуск решения
В этой задаче вы убедитесь, что служба веб-API, созданная в предыдущей задаче, работает должным образом. Вы будете использовать средства разработчика Internet Explorer F12 для записи сетевого трафика и проверки полного ответа от веб-службы API.
Замечание
Убедитесь, что Internet Explorer выбран в кнопке "Пуск ", расположенной на панели инструментов Visual Studio.
Нажмите клавишу F5 , чтобы запустить решение. Страница входа должна появиться в браузере.
Замечание
При запуске приложения запускается маршрут MVC по умолчанию, который по умолчанию сопоставляется с действием Index класса HomeController . Так как HomeController ограничен проверкой подлинности пользователей (помните, что вы украшали этот класс атрибутом авторизации в упражнении 1) и еще не прошел проверку подлинности пользователя, приложение перенаправляет исходный запрос на страницу входа.
Запуск решения
Нажмите кнопку "Регистрация" , чтобы создать нового пользователя.
Регистрация нового пользователя
На странице "Регистрация" введите имя пользователя и пароль, а затем нажмите кнопку "Зарегистрировать".
Страница регистрации
Приложение регистрирует новую учетную запись, а пользователь проходит проверку подлинности и перенаправляется обратно на домашнюю страницу.
Пользователь проходит проверку подлинности
В браузере нажмите клавишу F12 , чтобы открыть панель средств разработчика . Нажмите клавиши CTRL + 4 или щелкните значок сети , а затем нажмите зеленую кнопку со стрелкой, чтобы начать захват сетевого трафика.
Инициация захвата сети веб-API
Добавьте API/trivia к URL-адресу в адресной строке браузера. Теперь вы изучите сведения об ответе из метода действия Get в TriviaController.
Получение следующих данных вопроса через веб-API
Замечание
После завершения скачивания вам будет предложено выполнить действие с скачанным файлом. Оставьте диалоговое окно открытым, чтобы просмотреть содержимое ответа в окне "Разработчики".
Теперь вы проверите текст ответа. Для этого щелкните вкладку "Сведения" и щелкните текст ответа. Можно проверить, является ли скачанные данные объектом с параметрами свойств (который является списком объектов TriviaOption), идентификатором и заголовком, соответствующим классу TriviaQuestion.
Просмотр текста ответа веб-API
Вернитесь в Visual Studio и нажмите клавиши SHIFT +F5 , чтобы остановить отладку.
Упражнение 2. Создание интерфейса SPA
В этом упражнении вы сначала создадите веб-интерфейсную часть Geek Quiz, фокусируясь на взаимодействии с приложением Single-Page с помощью AngularJS. Затем вы улучшите пользовательский опыт с помощью CSS3 для выполнения расширенных анимаций и обеспечите визуальный эффект переключения контекста при переходе с одного вопроса на следующий.
Задача 1. Создание интерфейса SPA с помощью AngularJS
В этой задаче вы будете использовать AngularJS для реализации клиентской стороны приложения Geek Quiz. AngularJS — это платформа JavaScript с открытым исходным кодом, которая расширяет возможности приложений на основе браузера с помощью возможностей Model-View-Controller (MVC), упрощая разработку и тестирование.
Сначала необходимо установить AngularJS из консоли диспетчера пакетов Visual Studio. Затем вы создадите контроллер для управления поведением приложения Geek Quiz и представление для отображения вопросов и ответов с помощью движка шаблонов AngularJS.
Замечание
Дополнительные сведения об AngularJS см. в разделе [http://angularjs.org/](http://angularjs.org/).
Откройте Visual Studio Express 2013 для Интернета и откройте решение GeekQuiz.sln , расположенное в папке Source/Ex2-CreatingASPAInterface/Begin . Кроме того, можно продолжить работу с решением, полученным в предыдущем упражнении.
Откройте консоль диспетчера пакетов из Инструменты>Диспетчер пакетов NuGet. Введите следующую команду, чтобы установить пакет NuGet AngularJS.Core .
Install-Package AngularJS.CoreВ обозревателе решений щелкните правой кнопкой мыши папку "Скрипты " проекта GeekQuiz и выберите "Добавить |" Новая папка. Назовите папку app и нажмите Enter.
Щелкните правой кнопкой мыши папку приложения , которую вы только что создали, и выберите команду "Добавить" | Файл JavaScript.
Создание файла JavaScript
В диалоговом окне "Указание имени элемента" введите контроллер теста в текстовом поле "Имя элемента " и нажмите кнопку "ОК".
Именование нового файла JavaScript
В файлеquiz-controller.js добавьте следующий код, чтобы объявить и инициализировать контроллер AngularJS QuizCtrl .
(Фрагмент кода — 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'; }; });Замечание
Функция конструктора контроллера QuizCtrl ожидает вводимый параметр с именем $scope. Начальное состояние области должно быть настроено в функции конструктора путем подключения свойств к объекту $scope . Свойства содержат модель представления и будут доступны шаблону при регистрации контроллера.
Контроллер QuizCtrl определяется внутри модуля с именем QuizApp. Модули — это единицы работы, которые позволяют разбить приложение на отдельные компоненты. Основным преимуществом использования модулей является то, что код проще понять и облегчается модульное тестирование, повторное использование и удобство обслуживания.
Теперь вы добавите поведение в область, чтобы реагировать на события, активированные в представлении. Добавьте следующий код в конце контроллера QuizCtrl , чтобы определить следующую функциюQuestion в объекте $scope .
(Фрагмент кода — 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; }); }; };Замечание
Эта функция извлекает следующий вопрос из веб-API Trivia , созданного в предыдущем упражнении, и присоединяет данные вопроса к объекту $scope .
Вставьте следующий код в конец контроллера QuizCtrl , чтобы определить функцию sendAnswer в объекте $scope .
(Фрагмент кода — 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; }); }; };Замечание
Эта функция отправляет ответ, выбранный пользователем, в веб-API Trivia и сохраняет результат ( например, если ответ правильный или нет) в объекте $scope .
Функции nextQuestion и sendAnswer, приведённые выше, используют объект AngularJS $http для упрощения взаимодействия с веб-API через объект JavaScript XMLHttpRequest из браузера. AngularJS поддерживает другую службу, которая обеспечивает более высокий уровень абстракции для выполнения операций CRUD с ресурсом с помощью API RESTful. Объект AngularJS $resource имеет методы действий, обеспечивающие высокоуровневое поведение без необходимости взаимодействовать с объектом $http . Рассмотрите возможность использования объекта $resource в сценариях, требующих модели CRUD (дополнительные сведения см. в документации по $resource).
Следующим шагом является создание шаблона AngularJS, который определяет представление для теста. Для этого откройте файл Index.cshtml в представлениях | Домашняя папка и замените содержимое следующим кодом.
(Фрагмент кода — 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") }Замечание
Шаблон AngularJS — это декларативная спецификация, которая использует сведения из модели и контроллера для преобразования статической разметки в динамическое представление, которое пользователь видит в браузере. Ниже приведены примеры элементов AngularJS и атрибутов элементов, которые можно использовать в шаблоне:
- Директива ng-app указывает AngularJS на элемент DOM, который является корневым элементом приложения.
- Директива ng-controller присоединяет контроллер к DOM в точке объявления директивы.
- Нотация фигурных скобок {{ }} обозначает привязки к свойствам области видимости, определенным в контроллере.
- Директива ng-click используется для вызова функций, определенных в области в ответ на щелчки пользователей.
Откройте файл Site.css в папке "Содержимое " и добавьте следующие выделенные стили в конце файла, чтобы обеспечить внешний вид и представление теста.
(Фрагмент кода — 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; }
Задача 2. Запуск решения
В этой задаче вы будете выполнять решение с помощью нового пользовательского интерфейса, созданного с помощью AngularJS, чтобы ответить на некоторые вопросы теста.
Нажмите клавишу F5 , чтобы запустить решение.
Зарегистрируйте новую учетную запись пользователя. Для этого выполните действия по регистрации, описанные в упражнении 1, задаче 3.
Замечание
Если вы используете решение из предыдущего упражнения, вы можете войти с помощью учетной записи пользователя, созданной ранее.
Откроется домашняя страница, показывающая первый вопрос теста. Ответьте на вопрос, щелкнув один из вариантов. Это активирует функцию sendAnswer , определенную ранее, которая отправляет выбранный параметр в веб-API Trivia .
Ответ на вопрос
После нажатия одной из кнопок ответ должен появиться. Нажмите кнопку "Следующий вопрос" , чтобы отобразить следующий вопрос. Эта функция активирует следующую функциюQuestion , определенную в контроллере.
Запрос следующего вопроса
Следующий вопрос должен появиться. Продолжайте отвечать на вопросы столько раз, сколько вы хотите. После того как вы ответите на все вопросы, вернитесь к первому вопросу.
Следующий вопрос
Вернитесь в Visual Studio и нажмите клавиши SHIFT +F5 , чтобы остановить отладку.
Задача 3. Создание анимации переворота с помощью CSS3
В этой задаче вы будете использовать свойства CSS3 для выполнения насыщенных анимаций, добавив эффект переворота при ответе на вопрос и при извлечении следующего вопроса.
В обозревателе решений щелкните правой кнопкой мыши папку "Содержимое " проекта GeekQuiz и выберите "Добавить |" Существующий элемент....
Добавление существующего элемента в папку содержимого
В диалоговом окне "Добавить существующий элемент" перейдите в папку Source/Assets и выберите Flip.css. Нажмите кнопку Добавить.
Добавление файла Flip.css из ресурсов
Откройте только что добавленный файл Flip.css и проверьте его содержимое.
Найдите комментарий преобразования flip. Стили, указанные ниже, используют перспективу CSS и трансформацию rotateY для создания эффекта "переворачивания карточки".
/* 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); }Найдите комментарий скрытие задней панели во время переворачивания. Стиль ниже этого комментария скрывает заднюю сторону элемента, когда она не обращена к зрителю, задавая свойство CSS backface-visibility со значением hidden.
/* hide back of pane during flip */ .front, .back { -moz-backface-visibility: hidden; -webkit-backface-visibility: hidden; backface-visibility: hidden; }Откройте файл BundleConfig.cs в папке App_Start и добавьте ссылку на файл Flip.css в пакет стилей ~/Content/css.
bundles.Add(new StyleBundle("~/Content/css").Include( "~/Content/bootstrap.css", "~/Content/site.css", "~/Content/Flip.css"));Нажмите клавишу F5 , чтобы запустить решение и войти с помощью учетных данных.
Ответьте на вопрос, щелкнув один из вариантов. Обратите внимание на эффект переворачивания при переходе между режимами просмотра.
Ответ на вопрос с эффектом переворота
Нажмите кнопку "Следующий вопрос", чтобы получить следующий вопрос. Эффект переворачивания должен появиться снова.
Извлечение следующего вопроса с эффектом переворота
Сводка
Завершив эту практическую лабораторию, вы узнали, как:
- Создание контроллера веб-API ASP.NET с помощью шаблонов ASP.NET
- Реализуйте действие веб-API GET для получения следующего вопроса викторины.
- Реализация действия Web API Post для записи ответов на тест
- Установка AngularJS из консоли диспетчера пакетов Visual Studio
- Реализация шаблонов и контроллеров AngularJS
- Использование переходов CSS3 для выполнения эффектов анимации