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}} |
摘要:从最重要的页面开始吧锦标赛的表格。重启你的应用,看看搜索框。然后我们加入两个路由一个转向锦标赛表格,另一个转向车手详情。你所需要做的只是创建一个名为的文件,然后将锦标赛表格放在那里。结论我们已经介绍了开发一个简单应用所需的一切。
AngularJS是Google开源出来的一款 Javascript MVC 框架。利用AngularJS,你可以构建结构清晰、便于测试和维护的前端应用。
使用AngularJS,你可以通过directive去定义很多自己的HTML元素属性。AngularJS无缝衔接了HTML(view)和Javascript(model),这样你就不需要去过多地关注Dom如何变化,你只需专注的处理你的数据。
AngularJS和服务器通信非常方便。和大多数Javascript的MVC框架一样, 只要你的应用提供一个RESTful API,AngularJS就可以和你的服务器相配合。同时,AngularJS提供了基于XHR的服务,这将大大简化你的代码,也方便将可复用的服务抽象成API调用。
Raoni Boaventura提供了一个教程,一步一步地教你写一个简单的AngularJS应用,让我们一起来看一下吧。
为了简化问题,我们要做的是一个直接从网络上拉取信息的应用,比如,一个查看方程式赛车比赛信息的应用。直接用Ergast的api获取信息。
可以看一下这个demo,对我们要做一个什么样的应用有个大致的概念。
开动吧推荐使用augular-seed,提供了一个很好的项目骨架。
我们的应用的骨架大概是这样的:
现在要开始写代码了。从最重要的页面开始吧:锦标赛的表格。
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很像?不过,虽然它们很强大,我们不应该用它们去实现一些高层级的逻辑——这该交给directive。
理解基本的directive上面的模板里还有一些类似ng-attributes的语句,这些正是directive。
directive让AngularJS把特定的行为附加到DOM元素中。让我们看一下上面的模板中的例子:
ng-app 初始化你的应用,定义其作用域。在 AngularJS 中,同一页面可以有多个应用,ng-app 指令表明应用的首尾位置。
ng-controller 定义视图由哪个控制器负责。在我们的例子中,driversController提供了车手的列表(driversList)。
ng-repeat 这个最常用。当使用循环的时候,ng-repeat定义模板的范围。在我们的例子中,就driversList中的每个车手,ng-repeat会生成重复的行。
添加控制器当然,没有控制器,我们的视图什么也干不了。让我们在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变量将控制器和视图相连接。事实上,它储存了模板中会用到的所有数据。任何你加入的内容(比如我们的例子中的driversList)可以直接在视图中访问。现在我们先用一个静态的数据数组,稍后我们会把它换成API服务。
在app.js中加入:
angular.module("F1FeederApp", [ "F1FeederApp.controllers" ]);
这行代码让我们初始化了我们的应用,同时也登记了需要的依赖。稍后我们会回到这个文件。
好了,现在让我们把这一切在index.html中整合起来:
F-1 Feeder
Drivers Championship Standings | |||
---|---|---|---|
{{$index + 1}} | {{driver.Driver.givenName}} {{driver.Driver.familyName}} | {{driver.Constructors[0].name}} | {{driver.points}} |
现在你可以尝试运行下这个应用了。
如果你希望调试应用,建议看下Chrome的Batarang 插件。
从服务器获取信息既然我们已经知道如何展示这些数据了,现在该是我们从RESTful服务器获取信息的时候了。
AngularJS提供的$http和$resource帮助我们和服务器通讯。
$http是以XMLHttpRequest和[JSONP]为基础的抽象层,$resource则提供更高层的抽象。在这里我们使用$http。
为了将API调用从控制器中抽象出来,我们创建一个自己定制的服务,该服务将抓取我们需要的信息,将$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; });
开头两行,我们创建了一个名为F1FeederApp.services的新模块,并在ergastAPIservice模块内注册了服务。注意,我们将$http传递给了该服务。这就告诉了Angular的依赖注入引擎我们的新服务依赖于$http服务。
类似地,我们需要让Angular将我们的新模块包含到应用中。在app.js注册下即可:
angular.module("F1FeederApp", [ "F1FeederApp.controllers", "F1FeederApp.services" ]);
现在我们只需调整一下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; }); });
好了,重新启动一下应用,看看结果如何。注意我们完全没有改动模板,只是增加了一个nameFilter。让我们把这个变量用起来。
过滤器好极了!我们的控制器已经可以工作了。但是它只能显示一个车手的列表。让我们加一些功能吧。我们来实现一个简单的文本搜索框,可以过滤列表。将以下这行加入到index.html,加在标签下面:
现在我们要用上 ng-model 指令了。这个指令将文本框绑定到$scope.nameFilter变量,并且确保该变量的值会及时更新。现在让我们稍微调整下index.html,加上一行ng-repeat指令。
这一行告诉ng-repeat,在输出数据之前,车手数组先要经过nameFilter的过滤。
此刻就是双向数据绑定发挥威力的时候了:每次你在搜索框里键入一些值的时候,Angular会及时更新$scope.nameFilter的内容。由于绑定是双向的,所以nameFilter更新的时候,相应的指令(ng-repeat)也会获得新的数值,然后视图会立刻更新。
重启你的应用,看看搜索框。
注意,过滤器会搜索所有属性中的关键词,包括你不想包括的内容。假设你只想通过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); };现在回到index.html,更新包括ng-repeat的那行:
重新启动应用,现在你可以通过姓名搜索了。
路由接下来我们要创建一个车手详情页面,当我们点击车手的时候,我们就可以看到关于他的一些详细信息。
首先,我们在app.js里加入$routeProvider服务,这个服务将帮助我们处理应用路由。然后我们加入两个路由:一个转向锦标赛表格,另一个转向车手详情。
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寻找需要渲染的部分视图。等等!我们好像还没有部分视图?我们需要创建他们。
部分视图AngularJS允许你将路由绑定到特定的控制器和视图。不过我们首先需要告诉Angular在哪里渲染这些部分视图。这需要使用ng-view指令。修改一下你的index.html:
F-1 Feeder 现在,只要是通过应用路由浏览,Angular 就会加载相应的视图,并且
在标签处渲染。你所需要做的只是创建一个名为partials/drivers.html的文件,然后将锦标赛表格放在那里。同时我们也将将车手的姓名和详情页面连接起来。
Drivers Championship Standings {{$index + 1}} {{driver.Driver.givenName}} {{driver.Driver.familyName}} {{driver.Constructors[0].name}} {{driver.points}} 最后,让我们确定下详情页面要展示什么。一个总结了车手相关信息(比如生日、国籍)的页面,同时包括一个最近成绩的表格。在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提供给服务,这样我们就可以获取特定车手的信息了。修改一下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服务插入了车手控制器。这个服务允许我们使用$routeParams.id访问URL参数(比如:id)。
现在我们已经有数据了,我们只需要处理一下局部视图了。创建一个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之后,大致是这样的效果:
现在你的应用已经可以上线了。确认下路由能工作。你可以在index.html加入一个静态的菜单以加强导航。一切皆有可能。
结论我们已经介绍了开发一个简单应用所需的一切。最后别忘了,Angular是一个非常强大的框架。我们只是试了试水而已。以后有机会将向大家展示Angular区别于其他前端MVC框架的特性:可测试性。我们将评测使用Karma编写和运行测试的过程,介绍持续集成的工具Yeomen、Grunt和Bower,以及Angular的其他优势。敬请期待。
原文 A Step-by-Step Guide to Your First AngularJS App
编译 SegmentFault文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/77971.html
相关文章
你的第一个AngularJS应用--教程二:基架、建立和测试的工具
摘要:包括脚手架依赖管理准备测试包括单元测试和端到端测试。我们用来开发的工具有。是一个工具集,包含个核心组件,,和脚手架工具。当你正在做自己的一个项目时,使用哪些模块将取决于你自己。这个目录当然是测试文件。 介绍 有很多可用的工具可以帮助你开发AngularJS 应用,那些非常复杂的框架不在我的讨论范围之中,这也是我开始这系列教程的原因。 在第一部分,我们掌握了AngularJS框架的基本...
Day 2: AngularJS —— 对AngularJS的初步认识
摘要:开始使用现在创建一个名为的文件,它将会是一个基于的网上书店应用。这将初始化应用程序,并告诉要在这一部分活跃。将为每个元素增加元素。控制器和视图之间的粘合剂,而且会注入到。现在我们添加书籍数组的对象到对象,这个对象对视图是可见的。 编者注:我们发现了比较有趣的系列文章《30天学习30种新技术》,准备翻译,一天一篇更新,年终礼包。以下是第二天技术的译文。 昨晚我完爆了一天一技术的任务...
AngularJs 功能(三)--数据绑定丶作用域
摘要:功能数据绑定的双向数据绑定,一方面可以做到变化驱动了中元素变化,另一方面也可以做到元素的变化也会影响到。其次告诉,对页面上的这个进行双向数据绑定。第三告诉,在这个指令模版上显示这个的数据。作用域是一个把一个元素连结到上的对象。 功能 数据绑定 AngularJS的双向数据绑定,一方面可以做到model变化驱动了DOM中元素变化,另一方面也可以做到DOM元素的变化也会影响到Model。 ...
给自己挖个坑,开始去开发javascript富应用框架
摘要:是目前项目中正在用的框架。现在前端这块再次到了这样的瓶颈,所以决定自己开始开发和维护自己的一个框架。不强制绑定,但是会制定其他规则来避免用户手动请求。项目目前完成板块事件绑定及触法地址处理以及路由处理。 为什么要框架 随着电脑运算能力的不断提升,越来越多的网站开始将一些数据处理,简单的业务逻辑交予前端。于是前端,特别是所谓的 Webapp 中,出现了大量的数据处理以及业务逻辑,前端的...
发表评论
0条评论
shadajin
男|高级讲师
TA的文章
阅读更多
云服务器与云主机有什么不同-云主机和云服务器的区别?
阅读 2555·2021-09-22 15:25
趣米云:中秋优惠,VPS全场8折优惠,2核2G/香港三网CN2/10M带宽/月付30元
阅读 2962·2021-09-14 18:03
启明云端分享|GPIO的使用
阅读 1211·2021-09-09 09:33
经典的动态内存错误(上)
阅读 1699·2021-09-07 09:59
Sharktech:$129/月/2*E5-2678v3/64GB内存/1TB NVMe硬盘/不限流
阅读 2930·2021-07-29 13:50
网页的响应式布局
阅读 1500·2019-08-30 15:44
动手搞一个Promise
阅读 1715·2019-08-29 16:22
canvas画动态时钟
阅读 1287·2019-08-29 12:49
<阅读需要支付1元查看