Formula 1 2013 Results | ||||
---|---|---|---|---|
Round | Grand Prix | Team | Grid | Race |
{{race.round}} | {{race.raceName}} | {{race.Results[0].Constructor.name}} | {{race.Results[0].grid}} | {{race.Results[0].position}} |
摘要:從最重要的頁面開始吧錦標賽的表格。重啟你的應(yīng)用,看看搜索框。然后我們加入兩個路由一個轉(zhuǎn)向錦標賽表格,另一個轉(zhuǎn)向車手詳情。你所需要做的只是創(chuàng)建一個名為的文件,然后將錦標賽表格放在那里。結(jié)論我們已經(jīng)介紹了開發(fā)一個簡單應(yīng)用所需的一切。
AngularJS是Google開源出來的一款 Javascript MVC 框架。利用AngularJS,你可以構(gòu)建結(jié)構(gòu)清晰、便于測試和維護的前端應(yīng)用。
使用AngularJS,你可以通過directive去定義很多自己的HTML元素屬性。AngularJS無縫銜接了HTML(view)和Javascript(model),這樣你就不需要去過多地關(guān)注Dom如何變化,你只需專注的處理你的數(shù)據(jù)。
AngularJS和服務(wù)器通信非常方便。和大多數(shù)Javascript的MVC框架一樣, 只要你的應(yīng)用提供一個RESTful API,AngularJS就可以和你的服務(wù)器相配合。同時,AngularJS提供了基于XHR的服務(wù),這將大大簡化你的代碼,也方便將可復(fù)用的服務(wù)抽象成API調(diào)用。
Raoni Boaventura提供了一個教程,一步一步地教你寫一個簡單的AngularJS應(yīng)用,讓我們一起來看一下吧。
為了簡化問題,我們要做的是一個直接從網(wǎng)絡(luò)上拉取信息的應(yīng)用,比如,一個查看方程式賽車比賽信息的應(yīng)用。直接用Ergast的api獲取信息。
可以看一下這個demo,對我們要做一個什么樣的應(yīng)用有個大致的概念。
開動吧推薦使用augular-seed,提供了一個很好的項目骨架。
我們的應(yīng)用的骨架大概是這樣的:
現(xiàn)在要開始寫代碼了。從最重要的頁面開始吧:錦標賽的表格。
HTML大概是這個樣子的(為了提高可讀性,先忽略CSS):
Drivers Championship Standings | |||
---|---|---|---|
{{$index + 1}} | {{driver.Driver.givenName}} {{driver.Driver.familyName}} | {{driver.Constructors[0].name}} | {{driver.points}} |
我想你會注意到模板里面有一些{{ 和 }} 之類的表達式。我們可以在里面做一些計算。舉一些例子吧:
{{ 1 + 1 }} {{ 946757880 | date }} {{ user.name }}
是不是和javascript很像?不過,雖然它們很強大,我們不應(yīng)該用它們?nèi)崿F(xiàn)一些高層級的邏輯——這該交給directive。
理解基本的directive上面的模板里還有一些類似ng-attributes的語句,這些正是directive。
directive讓AngularJS把特定的行為附加到DOM元素中。讓我們看一下上面的模板中的例子:
ng-app 初始化你的應(yīng)用,定義其作用域。在 AngularJS 中,同一頁面可以有多個應(yīng)用,ng-app 指令表明應(yīng)用的首尾位置。
ng-controller 定義視圖由哪個控制器負責。在我們的例子中,driversController提供了車手的列表(driversList)。
ng-repeat 這個最常用。當使用循環(huán)的時候,ng-repeat定義模板的范圍。在我們的例子中,就driversList中的每個車手,ng-repeat會生成重復(fù)的行。
添加控制器當然,沒有控制器,我們的視圖什么也干不了。讓我們在controllers.js中添加一個driversController:
angular.module("F1FeederApp.controllers", []). controller("driversController", function($scope) { $scope.driversList = [ { Driver: { givenName: "Sebastian", familyName: "Vettel" }, points: 322, nationality: "German", Constructors: [ {name: "Red Bull"} ] }, { Driver: { givenName: "Fernando", familyName: "Alonso" }, points: 207, nationality: "Spanish", Constructors: [ {name: "Ferrari"} ] } ]; });
你可能注意到了我們將$scope傳遞給了控制器。$scope變量將控制器和視圖相連接。事實上,它儲存了模板中會用到的所有數(shù)據(jù)。任何你加入的內(nèi)容(比如我們的例子中的driversList)可以直接在視圖中訪問。現(xiàn)在我們先用一個靜態(tài)的數(shù)據(jù)數(shù)組,稍后我們會把它換成API服務(wù)。
在app.js中加入:
angular.module("F1FeederApp", [ "F1FeederApp.controllers" ]);
這行代碼讓我們初始化了我們的應(yīng)用,同時也登記了需要的依賴。稍后我們會回到這個文件。
好了,現(xiàn)在讓我們把這一切在index.html中整合起來:
F-1 Feeder
Drivers Championship Standings | |||
---|---|---|---|
{{$index + 1}} | {{driver.Driver.givenName}} {{driver.Driver.familyName}} | {{driver.Constructors[0].name}} | {{driver.points}} |
現(xiàn)在你可以嘗試運行下這個應(yīng)用了。
如果你希望調(diào)試應(yīng)用,建議看下Chrome的Batarang 插件。
從服務(wù)器獲取信息既然我們已經(jīng)知道如何展示這些數(shù)據(jù)了,現(xiàn)在該是我們從RESTful服務(wù)器獲取信息的時候了。
AngularJS提供的$http和$resource幫助我們和服務(wù)器通訊。
$http是以XMLHttpRequest和[JSONP]為基礎(chǔ)的抽象層,$resource則提供更高層的抽象。在這里我們使用$http。
為了將API調(diào)用從控制器中抽象出來,我們創(chuàng)建一個自己定制的服務(wù),該服務(wù)將抓取我們需要的信息,將$http封裝起來。在services.js中加入:
angular.module("F1FeederApp.services", []). factory("ergastAPIservice", function($http) { var ergastAPI = {}; ergastAPI.getDrivers = function() { return $http({ method: "JSONP", url: "http://ergast.com/api/f1/2013/driverStandings.json?callback=JSON_CALLBACK" }); } return ergastAPI; });
開頭兩行,我們創(chuàng)建了一個名為F1FeederApp.services的新模塊,并在ergastAPIservice模塊內(nèi)注冊了服務(wù)。注意,我們將$http傳遞給了該服務(wù)。這就告訴了Angular的依賴注入引擎我們的新服務(wù)依賴于$http服務(wù)。
類似地,我們需要讓Angular將我們的新模塊包含到應(yīng)用中。在app.js注冊下即可:
angular.module("F1FeederApp", [ "F1FeederApp.controllers", "F1FeederApp.services" ]);
現(xiàn)在我們只需調(diào)整一下controller.js,將ergastAPIservice作為依賴:
angular.module("F1FeederApp.controllers", []). controller("driversController", function($scope, ergastAPIservice) { $scope.nameFilter = null; $scope.driversList = []; ergastAPIservice.getDrivers().success(function (response) { //Dig into the responde to get the relevant data $scope.driversList = response.MRData.StandingsTable.StandingsLists[0].DriverStandings; }); });
好了,重新啟動一下應(yīng)用,看看結(jié)果如何。注意我們完全沒有改動模板,只是增加了一個nameFilter。讓我們把這個變量用起來。
過濾器好極了!我們的控制器已經(jīng)可以工作了。但是它只能顯示一個車手的列表。讓我們加一些功能吧。我們來實現(xiàn)一個簡單的文本搜索框,可以過濾列表。將以下這行加入到index.html,加在標簽下面:
現(xiàn)在我們要用上 ng-model 指令了。這個指令將文本框綁定到$scope.nameFilter變量,并且確保該變量的值會及時更新?,F(xiàn)在讓我們稍微調(diào)整下index.html,加上一行ng-repeat指令。
這一行告訴ng-repeat,在輸出數(shù)據(jù)之前,車手數(shù)組先要經(jīng)過nameFilter的過濾。
此刻就是雙向數(shù)據(jù)綁定發(fā)揮威力的時候了:每次你在搜索框里鍵入一些值的時候,Angular會及時更新$scope.nameFilter的內(nèi)容。由于綁定是雙向的,所以nameFilter更新的時候,相應(yīng)的指令(ng-repeat)也會獲得新的數(shù)值,然后視圖會立刻更新。
重啟你的應(yīng)用,看看搜索框。
注意,過濾器會搜索所有屬性中的關(guān)鍵詞,包括你不想包括的內(nèi)容。假設(shè)你只想通過Driver.givenName和Driver.familyName過濾:首先,在driversController文件的$scope.driversList = [];下加入這樣一行:
$scope.searchFilter = function (driver) { var keyword = new RegExp($scope.filterName, "i"); return !$scope.filterName || keyword.test(driver.Driver.givenName) || keyword.test(driver.Driver.familyName); };現(xiàn)在回到index.html,更新包括ng-repeat的那行:
重新啟動應(yīng)用,現(xiàn)在你可以通過姓名搜索了。
路由接下來我們要創(chuàng)建一個車手詳情頁面,當我們點擊車手的時候,我們就可以看到關(guān)于他的一些詳細信息。
首先,我們在app.js里加入$routeProvider服務(wù),這個服務(wù)將幫助我們處理應(yīng)用路由。然后我們加入兩個路由:一個轉(zhuǎn)向錦標賽表格,另一個轉(zhuǎn)向車手詳情。
angular.module("F1FeederApp", [ "F1FeederApp.services", "F1FeederApp.controllers", "ngRoute" ]). config(["$routeProvider", function($routeProvider) { $routeProvider. when("/drivers", {templateUrl: "partials/drivers.html", controller: "driversController"}). when("/drivers/:id", {templateUrl: "partials/driver.html", controller: "driverController"}). otherwise({redirectTo: "/drivers"}); }]);修改之后,訪問http://domain/#/drivers,這將加載driversController,然后在partials/drivers.html尋找需要渲染的部分視圖。等等!我們好像還沒有部分視圖?我們需要創(chuàng)建他們。
部分視圖AngularJS允許你將路由綁定到特定的控制器和視圖。不過我們首先需要告訴Angular在哪里渲染這些部分視圖。這需要使用ng-view指令。修改一下你的index.html:
F-1 Feeder 現(xiàn)在,只要是通過應(yīng)用路由瀏覽,Angular 就會加載相應(yīng)的視圖,并且
在標簽處渲染。你所需要做的只是創(chuàng)建一個名為partials/drivers.html的文件,然后將錦標賽表格放在那里。同時我們也將將車手的姓名和詳情頁面連接起來。
Drivers Championship Standings {{$index + 1}} {{driver.Driver.givenName}} {{driver.Driver.familyName}} {{driver.Constructors[0].name}} {{driver.points}} 最后,讓我們確定下詳情頁面要展示什么。一個總結(jié)了車手相關(guān)信息(比如生日、國籍)的頁面,同時包括一個最近成績的表格。在services.js里加入這些:
angular.module("F1FeederApp.services", []) .factory("ergastAPIservice", function($http) { var ergastAPI = {}; ergastAPI.getDrivers = function() { return $http({ method: "JSONP", url: "http://ergast.com/api/f1/2013/driverStandings.json?callback=JSON_CALLBACK" }); } ergastAPI.getDriverDetails = function(id) { return $http({ method: "JSONP", url: "http://ergast.com/api/f1/2013/drivers/"+ id +"/driverStandings.json?callback=JSON_CALLBACK" }); } ergastAPI.getDriverRaces = function(id) { return $http({ method: "JSONP", url: "http://ergast.com/api/f1/2013/drivers/"+ id +"/results.json?callback=JSON_CALLBACK" }); } return ergastAPI; });這次我們把車手的ID提供給服務(wù),這樣我們就可以獲取特定車手的信息了。修改一下controllers.js:
angular.module("F1FeederApp.controllers", []). /* Drivers controller */ controller("driversController", function($scope, ergastAPIservice) { $scope.nameFilter = null; $scope.driversList = []; $scope.searchFilter = function (driver) { var re = new RegExp($scope.filterName, "i"); return !$scope.filterName || re.test(driver.Driver.givenName) || re.test(driver.Driver.familyName); }; ergastAPIservice.getDrivers().success(function (response) { //Digging into the response to get the relevant data $scope.driversList = response.MRData.StandingsTable.StandingsLists[0].DriverStandings; }); }). /* Driver controller */ controller("driverController", function($scope, $routeParams, ergastAPIservice) { $scope.id = $routeParams.id; $scope.races = []; $scope.driver = null; ergastAPIservice.getDriverDetails($scope.id).success(function (response) { $scope.driver = response.MRData.StandingsTable.StandingsLists[0].DriverStandings[0]; }); ergastAPIservice.getDriverRaces($scope.id).success(function (response) { $scope.races = response.MRData.RaceTable.Races; }); });值得注意的是我們將$routeParams服務(wù)插入了車手控制器。這個服務(wù)允許我們使用$routeParams.id訪問URL參數(shù)(比如:id)。
現(xiàn)在我們已經(jīng)有數(shù)據(jù)了,我們只需要處理一下局部視圖了。創(chuàng)建一個partials/driver.html:
Formula 1 2013 Results Round Grand Prix Team Grid Race {{race.round}} {{race.raceName}} {{race.Results[0].Constructor.name}} {{race.Results[0].grid}} {{race.Results[0].position}} 注意這次我們用上了ng-show。只有當你提供的表達式是true的時候,它才會顯示HTML元素。在我們的例子中,只有當控制器加載了車手對象后才會顯示頭像。
完成加上一些CSS之后,大致是這樣的效果:
現(xiàn)在你的應(yīng)用已經(jīng)可以上線了。確認下路由能工作。你可以在index.html加入一個靜態(tài)的菜單以加強導航。一切皆有可能。
結(jié)論我們已經(jīng)介紹了開發(fā)一個簡單應(yīng)用所需的一切。最后別忘了,Angular是一個非常強大的框架。我們只是試了試水而已。以后有機會將向大家展示Angular區(qū)別于其他前端MVC框架的特性:可測試性。我們將評測使用Karma編寫和運行測試的過程,介紹持續(xù)集成的工具Yeomen、Grunt和Bower,以及Angular的其他優(yōu)勢。敬請期待。
原文 A Step-by-Step Guide to Your First AngularJS App
編譯 SegmentFault文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/77971.html
相關(guān)文章
你的第一個AngularJS應(yīng)用--教程二:基架、建立和測試的工具
摘要:包括腳手架依賴管理準備測試包括單元測試和端到端測試。我們用來開發(fā)的工具有。是一個工具集,包含個核心組件,,和腳手架工具。當你正在做自己的一個項目時,使用哪些模塊將取決于你自己。這個目錄當然是測試文件。 介紹 有很多可用的工具可以幫助你開發(fā)AngularJS 應(yīng)用,那些非常復(fù)雜的框架不在我的討論范圍之中,這也是我開始這系列教程的原因。 在第一部分,我們掌握了AngularJS框架的基本...
Day 2: AngularJS —— 對AngularJS的初步認識
摘要:開始使用現(xiàn)在創(chuàng)建一個名為的文件,它將會是一個基于的網(wǎng)上書店應(yīng)用。這將初始化應(yīng)用程序,并告訴要在這一部分活躍。將為每個元素增加元素??刂破骱鸵晥D之間的粘合劑,而且會注入到?,F(xiàn)在我們添加書籍數(shù)組的對象到對象,這個對象對視圖是可見的。 編者注:我們發(fā)現(xiàn)了比較有趣的系列文章《30天學習30種新技術(shù)》,準備翻譯,一天一篇更新,年終禮包。以下是第二天技術(shù)的譯文。 昨晚我完爆了一天一技術(shù)的任務(wù)...
AngularJs 功能(三)--數(shù)據(jù)綁定丶作用域
摘要:功能數(shù)據(jù)綁定的雙向數(shù)據(jù)綁定,一方面可以做到變化驅(qū)動了中元素變化,另一方面也可以做到元素的變化也會影響到。其次告訴,對頁面上的這個進行雙向數(shù)據(jù)綁定。第三告訴,在這個指令模版上顯示這個的數(shù)據(jù)。作用域是一個把一個元素連結(jié)到上的對象。 功能 數(shù)據(jù)綁定 AngularJS的雙向數(shù)據(jù)綁定,一方面可以做到model變化驅(qū)動了DOM中元素變化,另一方面也可以做到DOM元素的變化也會影響到Model。 ...
給自己挖個坑,開始去開發(fā)javascript富應(yīng)用框架
摘要:是目前項目中正在用的框架?,F(xiàn)在前端這塊再次到了這樣的瓶頸,所以決定自己開始開發(fā)和維護自己的一個框架。不強制綁定,但是會制定其他規(guī)則來避免用戶手動請求。項目目前完成板塊事件綁定及觸法地址處理以及路由處理。 為什么要框架 隨著電腦運算能力的不斷提升,越來越多的網(wǎng)站開始將一些數(shù)據(jù)處理,簡單的業(yè)務(wù)邏輯交予前端。于是前端,特別是所謂的 Webapp 中,出現(xiàn)了大量的數(shù)據(jù)處理以及業(yè)務(wù)邏輯,前端的...
發(fā)表評論
0條評論
shadajin
男|高級講師
TA的文章
閱讀更多
云服務(wù)器與云主機有什么不同-云主機和云服務(wù)器的區(qū)別?
閱讀 2567·2021-09-22 15:25
趣米云:中秋優(yōu)惠,VPS全場8折優(yōu)惠,2核2G/香港三網(wǎng)CN2/10M帶寬/月付30元
閱讀 2978·2021-09-14 18:03
啟明云端分享|GPIO的使用
閱讀 1228·2021-09-09 09:33
經(jīng)典的動態(tài)內(nèi)存錯誤(上)
閱讀 1712·2021-09-07 09:59
Sharktech:$129/月/2*E5-2678v3/64GB內(nèi)存/1TB NVMe硬盤/不限流
閱讀 2938·2021-07-29 13:50
網(wǎng)頁的響應(yīng)式布局
閱讀 1509·2019-08-30 15:44
動手搞一個Promise
閱讀 1723·2019-08-29 16:22
canvas畫動態(tài)時鐘
閱讀 1295·2019-08-29 12:49
<閱讀需要支付1元查看