文章出處

網絡營

下載網絡營訓練包

在傳統的Web應用程序中,客戶機(瀏覽器)通過請求頁面啟動與服務器的通信。然后,服務器處理請求,并將頁面的HTML發送給客戶端。在與頁面的后續交互中,用戶導航到鏈接或提交帶有數據的表單 - 新的請求將發送到服務器,流程將再次啟動:服務器處理請求并將新頁面發送到瀏覽器回應客戶要求的新動作。

在單頁面應用程序(SPA)中,整個頁面在初始請求之后加載到瀏覽器中,但后續的交互通過Ajax請求進行。這意味著瀏覽器必須僅更新已更改的頁面部分; 沒有必要重新加載整個頁面。SPA方法減少了應用程序響應用戶操作所花費的時間,從而導致更流暢的體驗。

SPA的架構涉及傳統Web應用程序中不存在的某些挑戰。然而,像ASP.NET Web API這樣的新興技術,像AngularJS這樣的JavaScript框架和CSS3提供的新的樣式功能使得設計和構建SPA變得非常簡單。

在這個動手實驗室,您將利用這些技術來實施基于SPA概念的瑣事網站Geek Quiz。您將首先使用ASP.NET Web API實現服務層,以公開所需的端點,以檢索測驗問題并存儲答案。然后,您將使用AngularJS和CSS3轉換效果構建一個豐富和響應的UI。

所有示例代碼和代碼段都包含在Web Camps Training Kit中,可從http://aka.ms/webcamps-trainingkit獲取

概觀

 

目標

在這個動手實驗中,您將學習如何:

  • 創建一個ASP.NET Web API服務來發送和接收JSON數據
  • 使用AngularJS創建響應式UI
  • 通過CSS3轉換增強UI體驗

 

先決條件

完成此動手實驗室需要以下內容:

 

建立

為了在這個動手實驗室中運行練習,你需要首先設置你的環境。

  1. 打開Windows資源管理器并瀏覽實驗室的“ 源”文件夾。
  2. 右鍵單擊Setup.cmd,然后選擇以管理員身份運行,啟動安裝過程,該過程將配置您的環境并安裝本實驗的Visual Studio代碼片段。
  3. 如果顯示“用戶帳戶控制”對話框,請確認該操作繼續。
注意

在運行安裝程序之前,請確保已經檢查了該實驗室的所有依賴項。

 

使用代碼片段

在整個實驗室文檔中,將指示您插入代碼塊。為方便起見,這些代碼大部分作為Visual Studio代碼片段提供,您可以從Visual Studio 2013中訪問,以避免手動添加。

注意

每個練習都附有一個起始解決方案,位于練習Begin文件夾中,可以讓您獨立于其他練習進行每項練習。請注意,在這些開始的解決方案中缺少在練習期間添加的代碼段,并且在完成練習之前可能無法正常工作。在練習的源代碼中,您還將找到一個包含Visual Studio解決方案End文件夾,其中包含完成相應練習中的步驟所產生的代碼。您可以使用這些解決方案作為指導,如果您需要額外的幫助,當您通過這個動手實驗室。


 

演習

這個動手實驗室包括以下練習:

  1. 創建Web API
  2. 創建SPA界面

預計完成本實驗的時間:60分鐘

注意

當您第一次啟動Visual Studio時,您必須選擇一個預定義的設置集合。每個預定義的集合都被設計為匹配特定的開發風格,并確定窗口布局,編輯器行為,智能感知代碼片段和對話框選項。本實驗中的過程描述了在使用“ 常規開發設置”集合時在Visual Studio中完成給定任務所需的操作如果您為開發環境選擇不同的設置集合,那么您應該考慮的步驟可能會有所不同。

 

練習1:創建Web API

SPA的關鍵部分之一是服務層。它負責處理由UI發送的Ajax調用,并響應于該調用返回數據。檢索的數據應以機器可讀格式呈現,以便客戶端進行解析和使用。

Web API框架是ASP.NET堆棧的一部分,旨在使HTTP服務變得容易,通常通過RESTful API發送和接收JSON或XML格式的數據。在本練習中,您將創建Web站點來托管Geek Quiz應用程序,然后實施后端服務,以使用ASP.NET Web API公開并保留測驗數據。

 

任務1 - 創建Geek測驗的初始項目

在此任務中,您將開始創建一個新的ASP.NET MVC項目,并支持基于Visual Studio附帶一個ASP.NET項目類型的ASP.NET Web API 一個ASP.NET統一了所有的ASP.NET技術,并提供了根據需要進行混合和匹配的選項。然后,您將添加實體框架的模型類和數據庫初始化器以插入測驗問題。

  1. 打開Visual Studio Express 2013 for Web,然后選擇File | 新項目...開始一個新的解決方案。

    創建新項目

    創建新項目

  2. 在“ 新建項目”對話框中,Visual C#|選擇ASP.NET Web應用程序 網頁標簽。確保選擇了.NET Framework 4.5,將其命名為GeekQuiz,選擇位置,然后單擊確定

    創建一個新的ASP.NET Web應用程序項目

    創建一個新的ASP.NET Web應用程序項目

  3. 在“ 新建ASP.NET項目”對話框中,選擇MVC模板并選擇Web API選項。此外,請確保“ 身份驗證”選項設置為“ 個人用戶帳戶”單擊確定繼續。

    使用MVC模板創建一個新項目,包括Web API組件

    使用MVC模板創建一個新項目,包括Web API組件

  4. 解決方案資源管理器中,右鍵單擊GeekQuiz項目Models文件夾,然后選擇Add | 現有項...

    添加現有項目

    添加現有項目

  5. 在“ 添加現有項目”對話框中,導航到“ 源/資產/模型”文件夾,然后選擇所有文件。單擊添加

    添加模型資產

    添加模型資產

    注意

    通過添加這些文件,您將添加數據模型,Entity Framework的數據庫上下文和Geek Quiz應用程序的數據庫初始化程序。

    實體框架(EF)是一種對象關系映射器(ORM),它使您能夠通過使用概念應用程序模型編程創建數據訪問應用程序,而不是直接使用關系存儲架構進行編程。您可以在這里了解有關實體框架的更多信息

    以下是剛剛添加的類的描述:

    • TriviaOption:表示與測驗問題相關聯的單個選項
    • TriviaQuestion:表示一個測驗問題,并通過Options屬性公開相關選項
    • TriviaAnswer:表示用戶響應測驗問題選擇的選項
    • TriviaContext:代表實體框架的Geek Quiz應用程序的數據庫環境。該類派生自DContext,并公開表示上述實體的集合的DbSet屬性。
    • TriviaDatabaseInitializer:實現了繼承自CreateDatabaseIfNotExistsTriviaContext的Entity Framework初始化器此類的默認行為是僅在不存在的情況下創建數據庫,才能插入“ 種子”方法中指定的實體
  6. 打開Global.asax.cs文件并添加以下using語句。

    C#
    using GeekQuiz.Models;
    
  7. Application_Start方法的開頭添加以下代碼,TriviaDatabaseInitializer設置為數據庫初始化程序。

    C#
    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);
        }
    }
    
  8. 修改Home控制器以限制對經過身份驗證的用戶的訪問。為此,請打開Controllers文件夾中HomeController.cs文件,并將Authorize屬性添加HomeController類定義。

    C#
    namespace GeekQuiz.Controllers
    {
        [Authorize]
        public class HomeController : Controller
        {
            public ActionResult Index()
            {
                return View();
            }
    
            ...
        }
    }
    
    注意

    授權過濾器檢查,看是否該用戶進行身份驗證。如果用戶未通過身份驗證,則返回HTTP狀態碼401(未經授權),而不調用該操作。您可以在全局,控制器級別或單個操作級別應用過濾器。

  9. 您現在將自定義網頁的布局和品牌。為此,請Views |中打開_Layout.cshtml文件 通過使用Geek Quiz替換My ASP.NET應用程序共享文件夾并更新<title>元素的內容

    CSHTML
    <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>
    
  10. 在同一個文件中,通過刪除關于聯系人鏈接并將主頁鏈接重命名播放更新導航欄另外,重命名應用程序名稱鏈接到Geek Quiz導航欄的HTML應如下所示。

    CSHTML
    <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>
    
  11. 通過使用Geek Quiz替換“ 我的ASP.NET應用程序”更新布局頁面的頁腳為此,請使用以下突出顯示的代碼替換<footer>元素的內容。

    HTML
    <div class="container body-content">
        @RenderBody()
        <hr />
        <footer>
            <p>&copy; @DateTime.Now.Year - Geek Quiz</p>
        </footer>
    </div>
    

 

任務2 - 創建TriviaController Web API

在上一個任務中,您創建了Geek Quiz Web應用程序的初始結構。您現在將構建一個簡單的Web API服務,它與測驗數據模型進行交互,并公開以下操作:

  • GET / api / trivia:從測驗列表中檢索下一個問題,由認證用戶回答。
  • POST / api / trivia:存儲由驗證的用戶指定的測驗答案。

您將使用Visual Studio提供的ASP.NET腳手架工具為Web API控制器類創建基準。

  1. 打開App_Start文件夾中WebApiConfig.cs文件。該文件定義了Web API服務的配置,就像路由映射到Web API控制器操作一樣。
  2. 在文件開頭添加以下using語句。

    C#
    using Newtonsoft.Json.Serialization;
    
  3. 將以下突出顯示的代碼添加到Register方法中,以全局配置Web API操作方法檢索的JSON數據的格式化程序。

    C#
    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自動屬性名稱轉換為駱駝的情況下,這是在JavaScript屬性名稱的一般慣例。

  4. 解決方案資源管理器中,右鍵單擊GeekQuiz項目Controllers文件夾,然后選擇Add | 新搭建的項目......

    創建一個新的腳手架物品

    創建一個新的腳手架物品

  5. 在“ 添加腳手架”對話框中,確保在左側窗格中選擇了“ 公共”節點。然后,在中央窗格中選擇Web API 2控制器 - 空模板,然后單擊添加

    選擇Web API 2控制器空模板

    選擇Web API 2控制器空模板

    注意

    ASP.NET腳手架是ASP.NET Web應用程序的代碼生成框架。Visual Studio 2013包括用于MVC和Web API項目的預安裝代碼生成器。當您希望快速添加與數據模型交互的代碼,以減少開發標準數據操作所需的時間,您應該在項目中使用腳手架。

    腳手架過程還確保所有所需的依賴關系都安裝在項目中。例如,如果您從一個空的ASP.NET項目開始,然后使用腳手架來添加一個Web API控制器,則所需的Web API NuGet軟件包和引用將自動添加到您的項目中。

  6. 在“ 添加控制器”對話框中,在“ 控制器名稱”文本框中鍵入TriviaController然后單擊“ 添加”

    添加Trivia控制器

    添加Trivia控制器

  7. 然后TriviaController.cs文件添加到GeekQuiz項目Controllers文件夾中,其中包含一個空的TriviaController類。在文件的開頭添加以下使用語句。

    (代碼片段 - AspNetWebApiSpa - Ex1 - TriviaControllerUsings

    C#
    using System.Data.Entity;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Web.Http.Description;
    using GeekQuiz.Models;
    
  8. TriviaController的開頭添加以下代碼,以便在控制器中定義,初始化和處理TriviaContext實例。

    (代碼片段 - AspNetWebApiSpa - Ex1 - TriviaControllerContext

    C#
    public class TriviaController : ApiController
    {
        private TriviaContext db = new TriviaContext();
    
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                this.db.Dispose();
            }
    
            base.Dispose(disposing);
        }
    }
    
    注意

    處置的方法TriviaController調用處置所述的方法TriviaContext例如,這確保了在由所述上下文對象中使用的所有資源被釋放TriviaContext實例設置或垃圾收集。這包括關閉Entity Framework打開的所有數據庫連接。

  9. TriviaController的末尾添加以下幫助方法此方法從數據庫中檢索以下問題以由指定的用戶回答。

    (代碼片段 - AspNetWebApiSpa - Ex1 - TriviaControllerNextQuestion

    C#
    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);
    }
    
  10. 將以下Get操作方法添加TriviaController類中。此操作方法調用上一步中定義NextQuestionAsync幫助器方法來檢索已驗證用戶的下一個問題。

    (代碼片段 - AspNetWebApiSpa - Ex1 - TriviaControllerGetAction

    C#
    // 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);
    }
    
  11. TriviaController的末尾添加以下幫助方法該方法將指定的答案存儲在數據庫中,并返回一個布爾值,指示答案是否正確。

    (代碼片段 - AspNetWebApiSpa - Ex1 - TriviaControllerStoreAsync

    C#
    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;
    }
    
  12. 將以下Post操作方法添加TriviaController類中。此操作方法將答案與經過身份驗證的用戶相關聯,并調用StoreAsync幫助程序方法。然后,它發送一個響應與由輔助方法返回的布爾值。

    (代碼段 - AspNetWebApiSpa - Ex1 - TriviaControllerPostAction

    C#
    // 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);
    }
    
  13. 修改Web API控制器以通過將授權屬性添加TriviaController類定義來限制對經過身份驗證的用戶的訪問

    C#
    [Authorize]
    public class TriviaController : ApiController
    {
        ...
    }
    

 

任務3 - 運行解決方案

在此任務中,您將驗證您在前一任務中構建的Web API服務是否按預期工作。您將使用Internet Explorer F12開發人員工具捕獲網絡流量并檢查Web API服務的完整響應。

注意

確保在Visual Studio工具欄上的“ 開始”按鈕中選擇了Internet Explorer

Internet Explorer選項

  1. F5運行解決方案。在登錄頁面應該出現在瀏覽器中。

    注意

    當應用程序啟動時,默認的MVC路由被觸發,默認情況下映射到HomeControllerIndex操作由于HomeController僅限于經過身份驗證的用戶(請記住,您使用練習1中Authorize屬性來修飾該類),并且還沒有用戶認證,應用程序將原始請求重定向到登錄頁面。

    運行解決方案

    運行解決方案

  2. 單擊注冊以創建新用戶。

    注冊新用戶

    注冊新用戶

  3. 注冊頁面中,輸入用戶名密碼,然后單擊注冊

    注冊頁面

    注冊頁面

  4. 應用程序注冊新帳戶,用戶被認證并重新定向到主頁。

    用戶進行身份驗證

    用戶進行身份驗證

  5. 在瀏覽器中,按F12打開“ 開發人員工具”面板。CTRL + 4或單擊網絡圖標,然后單擊綠色箭頭按鈕開始捕獲網絡流量。

    啟動Web API網絡捕獲

    啟動Web API網絡捕獲

  6. 在瀏覽器地址欄中的URL 附加api / trivia您現在將從TriviaController中Get操作方法檢查響應的詳細信息

    通過Web API檢索下一個問題數據

    通過Web API檢索下一個問題數據

    注意

    一旦下載完成,系統將提示您對下載的文件進行操作。讓對話框打開,以便能夠通過開發人員工具窗口來觀看響應內容。

  7. 現在你將檢查身體的反應。為此,請單擊詳細信息選項卡,然后單擊響應正文您可以檢查下載的數據是否與具有對應于TriviaQuestion的屬性選項(它是TriviaOption對象的列表),id標題的對象

    查看Web API響應體

    查看Web API響應體

  8. 返回到Visual Studio,然后按SHIFT + F5停止調試。

 

練習2:創建SPA界面

在本練習中,您將首先構建Geek Quiz的Web前端部分,重點介紹使用AngularJS的單頁應用程序交互然后,您將通過CSS3增強用戶體驗,以執行豐富的動畫,并在從一個問題轉換到下一個問題時提供上下文切換的視覺效果。

 

任務1 - 使用AngularJS創建SPA接口

在這個任務中,您將使用AngularJS來實現Geek Quiz應用程序的客戶端。AngularJS是一個開放源碼的JavaScript框架,通過模型 - 視圖 - 控制器(MVC)功能來增強基于瀏覽器的應用程序,有助于開發和測試。

您將首先從Visual Studio的軟件包管理器控制臺安裝AngularJS。然后,您將創建控制器以提供Geek Quiz應用程序的行為和使用AngularJS模板引擎呈現測驗問題和答案的視圖。

注意

有關AngularJS的更多信息,請參閱[http://angularjs.org/](http://angularjs.org/))

  1. 打開Visual Studio Express 2013 for Web,并打開位于Source / Ex2-CreatingASPAInterface / Begin文件夾中GeekQuiz.sln解決方案或者,您可以繼續在上一個練習中獲得的解決方案。
  2. 工具 | 打開包管理器控制臺 圖書館包裹經理鍵入以下命令來安裝AngularJS.Core NuGet包。

    電源外殼
    Install-Package AngularJS.Core
    
  3. 解決方案資源管理器中,右鍵單擊GeekQuiz項目腳本文件夾,然后選擇添加 新建文件夾命名文件夾應用程序,然后按Enter鍵
  4. 右鍵單擊剛剛創建應用程序文件夾,然后選擇添加| JavaScript文件

    創建一個新的JavaScript文件

    創建一個新的JavaScript文件

  5. 在“ 指定項目名稱”對話框中,在“ 項目名稱”文本框中鍵入quiz-controller然后單擊“ 確定”

    命名新的JavaScript文件

    命名新的JavaScript文件

  6. quiz-controller.js文件中,添加以下代碼來聲明和初始化AngularJS QuizCtrl控制器。

    (代碼片段 - AspNetWebApiSpa - Ex2 - AngularQuizController

    JavaScript的
    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模塊是工作單元,可以將您的應用程序分解成單獨的組件。使用模塊的主要優點是代碼更容易理解,便于單元測試,可重用性和可維護性。

  7. 您現在將向作用域添加行為,以便對從視圖觸發的事件作出反應。QuizCtrl控件的末尾添加以下代碼,以定義$ scope對象中nextQuestion函數

    (代碼片段 - AspNetWebApiSpa - Ex2 - AngularQuizControllerNextQuestion

    JavaScript的
    .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;
            });
        };
    };
    
    注意

    此函數從上一個練習中創建Trivia Web API中檢索下一個問題,并將問題數據附加到$ scope對象。

  8. QuizCtrl控件的末尾插入以下代碼,以定義$ scope對象中sendAnswer函數

    (代碼片段 - AspNetWebApiSpa - Ex2 - AngularQuizControllerSendAnswer

    JavaScript的
    .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;
            });
        };
    };
    
    注意

    此功能將用戶選擇的答案發送到Trivia Web API,并存儲結果,如果答案是否正確,則在$ scope對象中。

    上述的NextQuestionsendAnswer函數使用AngularJS $ http對象通過瀏覽器中的XMLHttpRequest JavaScript對象抽象與Web API的通信。AngularJS支持另一種服務,它通過RESTful API為資源執行CRUD操作提供了更高的抽象級別。AngularJS $資源對象具有提供高級行為的操作方法,而不需要與$ http對象進行交互考慮在需要CRUD模型的場景中使用$資源對象(前提信息,請參閱$資源文檔)。

  9. 下一步是創建定義測驗視圖的AngularJS模板。為此,請Views |中打開Index.cshtml文件 文件夾,并用以下代碼替換內容。

    (Code Snippet - AspNetWebApiSpa - Ex2 - GeekQuizView

    CSHTML
    @{
        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-應用指令告訴AngularJS代表應用程序的根元素的DOM元素。
    • NG-控制器指令附加一個控制器在其中指令申報點的DOM。
    • 大括號符號{{}}表示綁定到控制器中定義的范圍屬性。
    • NG-點擊指令用于調用響應于用戶點擊在范圍中定義的功能。
  10. 打開Content文件夾中Site.css文件,并在文件末尾添加以下突出顯示的樣式,以提供測驗視圖的外觀。

    (代碼片段 - AspNetWebApiSpa - Ex2 - GeekQuizStyles

    CSS
    .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構建的新用戶界面來執行解決方案,以回答一些測驗問題。

  1. F5運行解決方案。
  2. 注冊一個新的用戶帳號。為此,請按照練習1,任務3中所述的注冊步驟進行操作。

    注意

    如果您使用上一個練習中的解決方案,您可以使用之前創建的用戶帳戶登錄。

  3. 主頁頁面應該出現,顯示了測驗的第一個問題。通過單擊其中一個選項來回答問題。這將觸發先前定義sendAnswer函數,該函數將選定的選項發送到Trivia Web API。

    回答一個問題

    回答一個問題

  4. 點擊其中一個按鈕后,應該會出現答案。單擊下一個問題以顯示以下問題。這將觸發控制器中定義nextQuestion函數。

    請求下一個問題

    請求下一個問題

  5. 下一個問題應該出現。繼續多次回答問題。完成所有問題后,您應該回到第一個問題。

    另一個問題

    下一個問題

  6. 返回到Visual Studio,然后按SHIFT + F5停止調試。

 

任務3 - 使用CSS3創建翻轉動畫

在這個任務中,您將使用CSS3屬性來執行豐富的動畫,通過在問題回答和下一個問題被檢索時添加翻轉效果。

  1. 解決方案資源管理器中,右鍵單擊GeekQuiz項目的“ 內容”文件夾,然后選擇“ 添加” 現有項...

    將現有項目添加到“內容”文件夾

    將現有項目添加到“內容”文件夾

  2. 在“ 添加現有項目”對話框中,導航到“ 源/資源”文件夾,然后選擇“ Flip.css”單擊添加

    從資產添加Flip.css文件

    從資產添加Flip.css文件

  3. 打開剛剛添加Flip.css文件并檢查其內容。
  4. 找到翻轉變換注釋。該評論下方的樣式使用CSS 透視圖rotateY轉換來生成“卡片翻轉”效果。

    CSS
    /* 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);
        }
    
  5. 在翻蓋評論期間找到窗格隱藏通過將背景可見性 CSS屬性設置為隱藏,該注釋下方的樣式通過將背面可見性 CSS屬性設置為隱藏,從而隱藏了面部背面的背面

    CSS
    /* hide back of pane during flip */
    .front, .back {
        -moz-backface-visibility: hidden;
        -webkit-backface-visibility: hidden;
        backface-visibility: hidden;
    }
    
  6. 打開App_Start文件夾中BundleConfig.cs文件,并將引用添加到“〜/ Content / css”樣式包中Flip.css文件

    C#
    bundles.Add(new StyleBundle("~/Content/css").Include(
        "~/Content/bootstrap.css",
        "~/Content/site.css",
        "~/Content/Flip.css"));
    
  7. F5運行解決方案并使用憑據登錄。
  8. 通過點擊其中一個選項來回答問題。注意在視圖之間轉換時的翻轉效果。

    回答一個具有翻轉效果的問題

    回答一個具有翻轉效果的問題

  9. 單擊下一個問題以檢索以下問題。翻轉效果應再次出現。

    使用翻轉效果檢索以下問題

    使用翻轉效果檢索以下問題


 

概要

通過完成這個動手實驗,你已經學會了如何:

  • 使用ASP.NET腳手架創建一個ASP.NET Web API控制器
  • 實施Web API獲取操作以檢索下一個測驗問題
  • 實施Web API Post操作來存儲測驗答案
  • 從Visual Studio包管理器控制臺安裝AngularJS
  • 實施AngularJS模板和控制器
  • 使用CSS3轉換來執行動畫效果
 

文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜

    大師兄 發表在 痞客邦 留言(0) 人氣()