Hello {{yourname || 'World'}}! 运行效果 Yourname: World HelloWorld! 打开网页应看到如下效果: 该示例有一下几点重要的注意事项: 文本输入指令 绑定到一个叫 yourname 的模型变量。 双大括号标记将 yourname 模型变量添加到问候语文本。 你不需要为该应用另外注册一个事件侦听器或添加事件处理程序! 现在试着在输入框中键入您的名称,您键入的名称将立即更新显示在问候语中。这就是 AngularJS双向数据绑定的概念。输入框的任何更改会立即反映到模型变量(一个方向),模型变量 的任何更改都会立即反映到问候语文本中(另一方向)。 AngularJS应用的解析 本节描述AngularJS应用程序的三个组成部分,并解释它们如何映射到模型-视图-控制器设计模 式: 模板(Templates) 模板是您用HTML和CSS编写的文件,展现应用的视图。您可给HTML添加新的元素、属性标 记,作为AngularJS编译器的指令。AngularJS编译器是完全可扩展的,这意味着通过AngularJS您可 以在HTML中构建您自己的HTML标记! 应用程序逻辑(Logic)和行为(Behavior) 应用程序逻辑和行为是您用JavaScript定义的控制器。AngularJS与标准AJAX应用程序不同,您 不需要另外编写侦听器或DOM控制器,因为它们已经内置到AngularJS中了。这些功能使您的应用程 序逻辑很容易编写、测试、维护和理解。 模型数据(Data) 模型是从AngularJS作用域对象的属性引申的。模型中的数据可能是Javascript对象、数组或基本 类型,这都不重要,重要的是,他们都属于AngularJS作用域对象。 AngularJS通过作用域来保持数据模型与视图界面UI的双向同步。一旦模型状态发生改变, AngularJS会立即刷新反映在视图界面中,反之亦然。 下面的插图显示了AngularJS应用的各部分,以及它们协同工作原理: AngularJS中文社区&&AngularJS英文官网&&代码许可The MIT License&&文档许可CC BY 3.0 ©2012AngularJS.cn|PoweredbyWordPress&bbPress|[湘ICP备12011607] 《AngularJS快速开始》上有1条评论 关于angularjs AngularJS中国社区 查看angularjs发表的文章→ 此外,AngularJS还提供了一些非常有用的服务特性: 1. 底层服务包括依赖注入,XHR、缓存、URL路由和浏览器抽象服务。 2. 您还可以扩展和添加自己特定的应用服务。 3. 这些服务可以让您非常方便的编写WEB应用。 版权声明:中文文档AngularJS中文社区&&英文文档AngularJS官网&&代码许可The MIT License&&文档许可CC BY 3.0 angularjs发表在入门教程分类,标签AngularJS、入门教程。将本文加入收藏夹。 angularjs在2012年9月16日09:53说道:登录以回复 朋友们有疑问或者建议尽管留言 要发表评论,您必须先登录。 AngularJS入门教程00:引导程序 发表于2012年9月15日angularjs 我们现在开始准备编写AngularJS应用——phonecat。这一步骤(步骤0),您将会熟悉重要的 源代码文件,学习启动包含AngularJS种子项目的开发环境,并在浏览器端运行应用。 1. 进入angular-phonecat目录,运行如下命令: git checkout -f step-0 该命令将重置phonecat项目的工作目录,建议您在每一学习步骤运行此命令,将命令中的数字改 成您学习步骤对应的数字,该命令将清除您在工作目录内做的任何更改。 1. 按照下面的操作您可以在浏览器中运行应用: node.js用户: A. 可以在独立的命令行终端运行 ./scripts/web-server.js 或者 node scripts/web-server.js 来启动服务器,启动后命令行终端将会提示 Http Server running at http://localhost:8000 ,请不要关闭该终端,关闭该终端即关闭了服务器; B. 在浏览器中输入http://localhost:8000/app/index.html来访问我们的应用。 使用其它HTTP服务器的用户: A. 请配置服务器使其驱动angular-phonecat项目; B. 在浏览器中输入 http://localhost:[port-number]/[context-path]/app/index.html 来访 问我们的应用。 现在,在浏览器中您应该已经看到了我们的初始应用,很简单,但说明我们的项目已经可以运行 了。 应用中显示的“Nothinghereyet!”是由如下HTML代码构建而成,代码中包含了AngularJS的 关键元素,正是我们需要学习的。 app/index.html:
Nothing here {{'yet' + '!'}}
代码在做什么呢? ng-app 指令: ng-app 指令标记了AngularJS脚本的作用域,在 中添加 ng-app 属性即说明整 个 都是AngularJS脚本作用域。开发者也可以在局部使用 ng-app 指令,如 ,则AngularJS脚本仅在该
中运行。 AngularJS脚本标签: ← 上一篇 下一篇 → 资讯 文档 社区 关于 搜索 注册登录 这行代码载入angular.js脚本,当浏览器将整个HTML页面载入完毕后将会执行该angular.js脚 本,angular.js脚本运行后将会寻找含有 ng-app 指令的HTML标签,该标签即定义了AngularJS应用 的作用域。 双大括号绑定的表达式: 标签里面的 ng-repeat="phone in phones" 语句是一个AngularJS迭代器。这个迭代器告诉 AngularJS用第一个 标签作为模板为列表中的每一部手机创建一个 元素。 正如我们在第0步时学到的,包裹在 phone.name 和 phone.snippet 周围的花括号标识着数据绑定。和 常量计算不同的是,这里的表达式实际上是我们应用的一个数据模型引用,这些我们 在 PhoneListCtrl 控制器里面都设置好了。 ← 上一篇 下一篇 → 资讯 文档 社区 关于 搜索 注册登录 模型和控制器 在 PhoneListCtrl 控制器里面初始化了数据模型(这里只不过是一个包含了数组的函数,数组中 存储的对象是手机数据列表): app/js/controller.js: function PhoneListCtrl($scope) { $scope.phones = [ {"name": "Nexus S", "snippet": "Fast just got faster with Nexus S."}, {"name": "Motorola XOOM™ with Wi-Fi", "snippet": "The Next, Next Generation tablet."}, {"name": "MOTOROLA XOOM™", "snippet": "The Next, Next Generation tablet."} ]; } 尽管控制器看起来并没有起到什么控制的作用,但是它在这里起到了至关重要的作用。通过给定 我们数据模型的语境,控制器允许我们建立模型和视图之间的数据绑定。我们是这样把表现层,数据 和逻辑部件联系在一起的: PhoneListCtrl ——控制器方法的名字(在JS文件 controllers.js 中)和 标签里面 的ngController指令的值相匹配。 手机的数据此时与注入到我们控制器函数的作用域( $scope )相关联。当应用启动之后,会有一个根 作用域被创建出来,而控制器的作用域是根作用域的一个典型后继。这个控制器的作用域对所有 标记内部的数据绑定有效。 AngularJS的作用域理论非常重要:一个作用域可以视作模板、模型和控制器协同工作的粘接 器。AngularJS使用作用域,同时还有模板中的信息,数据模型和控制器。这些可以帮助模型和视图分 离,但是他们两者确实是同步的!任何对于模型的更改都会即时反映在视图上;任何在视图上的更改 都会被立刻体现在模型中。 想要更加深入理解AngularJS的作用域,请参看AngularJS作用域文档。 测试 “AngularJS方式”让开发时代码测试变得十分简单。让我们来瞅一眼下面这个为控制器新添加 的单元测试: test/unit/controllersSpec.js: describe('PhoneCat controllers', function() { describe('PhoneListCtrl', function(){ it('should create "phones" model with 3 phones', function() { var scope = {}, ctrl = new PhoneListCtrl(scope); expect(scope.phones.length).toBe(3); }); }); }); 这个测试验证了我们的手机数组里面有三条记录(暂时无需弄明白这个测试脚本)。这个例子显 示出为AngularJS的代码创建一个单元测试是多么的容易。正因为测试在软件开发中是必不可少的环 节,所以我们使得在AngularJS可以轻易地构建测试,来鼓励开发者多写它们。 在写测试的时候,AngularJS的开发者倾向于使用Jasmine行为驱动开发(BBD)框架中的语法。 尽管AngularJS没有强迫你使用Jasmine,但是我们在教程里面所有的测试都使用Jasmine编写。你可 以在Jasmine的官方主页或者JasmineWiki上获得相关知识。 基于AngularJS的项目被预先配置为使用JsTestDriver来运行单元测试。你可以像下面这样运行测 试: 1. 在一个单独的终端上,进入到 angular-phonecat 目录并且运行 ./scripts/test-server.sh 来启动测 试(Windows命令行下请输入 .\scripts\test-server.bat 来运行脚本,后面脚本命令运行方式类 似); 2. 打开一个新的浏览器窗口,并且转到http://localhost:9876; 3. 选择“Capturethisbrowserinstrictmode”。 这个时候,你可以抛开你的窗口不管然后把这事忘了。JsTestDriver会自己把测试跑完并且 把结果输出在你的终端里。 4. 运行 ./scripts/test.sh 进行测试。 你应当看到类似于如下的结果: Chrome: Runner reset. . Total 1 tests (Passed: 1; Fails: 0; Errors: 0) (2.00 ms) Chrome 19.0.1084.36 Mac OS: Run 1 tests (Passed: 1; Fails: 0; Errors 0) (2.00 ms) 耶!测试通过了!或者没有... 注意:如果在你运行测试之后发生了错误,关闭浏览器然后回到终端关了脚本,然后在重新 来一边上面的步骤。 练习 为 index.html 添加另一个数据绑定。例如:
现在让数据模型表达式的 i 增加1:
确定把 toBe(3) 改成 toBe(4) 之后单元测试失败,然后重新跑一遍 ./scripts/test.sh 脚本 总结 你现在拥有一个模型,视图,控制器分离的动态应用了,并且你随时进行了测试。现在,你可以 进入到步骤3来为应用加入全文检索功能了。 版权声明:中文文档AngularJS中文社区&&英文文档AngularJS官网&&代码许可The MIT License&&文档许可CC BY 3.0 furtherLee发表在入门教程分类,标签AngularJS、furtherLee、入门教程。将本文加入收藏夹。 AngularJS中文社区&&AngularJS英文官网&&代码许可The MIT License&&文档许可CC BY 3.0 ©2012AngularJS.cn|PoweredbyWordPress&bbPress|[湘ICP备12011607] 《AngularJS入门教程02:AngularJS模板》上有2条评论 lovexiaobai在2013年1月26日15:51说道:登录以回复 在step-0的文件夹里面用gitcheckout-fstep-0重置之后少了文件就是test/lib/下面的三个测试文 件。所以用./scripts/test-server.sh启动服务器测试就有问题。 lovexiaobai在2013年1月26日11:01说道:登录以回复 为什么我运行./scripts/test.sh进行测试,没有出现4下面的结果。? 要发表评论,您必须先登录。 AngularJS入门教程03:迭代器过滤 发表于2012年9月22日furtherLee 我们在上一步做了很多基础性的训练,所以现在我们可以来做一些简单的事情喽。我们要加入全 文检索功能(没错,这个真的非常简单!)。同时,我们也会写一个端到端测试,因为一个好的端到 端测试可以帮上很大忙。它监视着你的应用,并且在发生回归的时候迅速报告。 请重置工作目录: git checkout -f step-3 我们的应用现在有了一个搜索框。注意到页面上的手机列表随着用户在搜索框中的输入而变化。 步骤2和步骤3之间最重要的不同在下面列出。你可以在GitHub里看到完整的差别。 控制器 我们对控制器不做任何修改 模板 app/index.html: 我们现在添加了一个 标签,并且使用AngularJS的$filter函数来处理ngRepeat指令的 输入。 这样允许用户输入一个搜索条件,立刻就能看到对电话列表的搜索结果。我们来解释一下新的代 码: 数据绑定:这是AngularJS的一个核心特性。当页面加载的时候,AngularJS会根据输入框的属性值名 字,将其与数据模型中相同名字的变量绑定在一起,以确保两者的同步性。 在这段代码中,用户在输入框中输入的数据名字称作 query ,会立刻作为列表迭代器 ( phone in phones | filter: query`)其过滤器的输入。当数据模型引起迭代器输入变化的 时候,迭代器可以高效得更新DOM将数据模型最新的状态反映出来。 ← 上一篇 下一篇 → 资讯 文档 社区 关于 搜索 注册登录 使用 filter 过滤器:filter函数使用 query 的值来创建一个只包含匹配 query 记录的新数组。 ngRepeat 会根据 filter 过滤器生成的手机记录数据数组来自动更新视图。整个过程对于 开发者来说都是透明的。 测试 在步骤2,我们学习了编写和运行一个测试的方法。单元测试用来测试我们用js编写的控制器和其 他组件都非常方便,但是不能方便的对DOM操作和应用集成进行测试。对于这些来说,端到端测试是 一个更好的选择。 搜索特性是完全通过模板和数据绑定实现的,所以我们的第一个端到端测试就来验证这些特性是 否符合我们的预期。 test/e2e/scenarios.js: describe('PhoneCat App', function() { describe('Phone list view', function() { beforeEach(function() { browser().navigateTo('../../app/index.html'); }); it('should filter the phone list as user types into the search box', function() { expect(repeater('.phones li').count()).toBe(3); input('query').enter('nexus'); expect(repeater('.phones li').count()).toBe(1); input('query').enter('motorola'); expect(repeater('.phones li').count()).toBe(2); }); }); }); 尽管这段测试代码的语法看起来和我们之前用Jasmine写的单元测试非常像,但是端到端测试使 用的是AngularJS端到端测试器提供的接口。 运行一个端到端测试,在浏览器新标签页中打开下面任意一个: node.js用户:http://localhost:8000/test/e2e/runner.html 使用其他http服务器的用户: http://localhost:[port-number]/[context- path]/test/e2e/runner.html 访客:http://angular.github.com/angular-phonecat/step-3/test/e2e/runner.html 这个测试验证了搜素框和迭代器被正确地集成起来。你可以发现,在AngularJS里写一个端到端 测试多么的简单。尽管这个例子仅仅是一个简单的测试,但是用它来构建任何一个复杂、可读的端到 端测试都很容易。 AngularJS中文社区&&AngularJS英文官网&&代码许可The MIT License&&文档许可CC BY 3.0 ©2012AngularJS.cn|PoweredbyWordPress&bbPress|[湘ICP备12011607] 练习 在 index.html 模板中添加一个 {{query}} 绑定来实时显示 query 模型的当前值,然后观察他们是如 何根据输入框中的值而变化。 现在我们来看一下我们怎么让 query 模型的值出现在HTML的页面标题上。 你或许认为像下面这样在 title 标签上加上一个绑定就行了: Google Phone Gallery: {{query}} 但是,当你重载页面的时候,你根本没办法得到期望的结果。这是因为 query 模型仅仅 在 body 元素定义的作用域内才有效。 如果你想让 元素绑定上 query 模型,你必须把 ngController 声明移 动到 HTML 元素上,因为它是 title 和 body 元素的共同祖先。 一定要注意把 body 元素上的 ng-controller 声明给删了。 当绑定两个花括号在 title 元素上可以实现我们的目标,但是你或许发现了,页面正加载 的时候它们已经显示给用户看了。一个更好的解决方案是使用ngBind或者ngBindTemplate指 令,它们在页面加载时对用户是不可见的: Google Phone Gallery 在 test/e2e/scenarios.js 的 describe 块中加入下面这些端到端测试代码: it('should display the current filter value within an element with id "status"', function() { expect(element('#status').text()).toMatch(/Current filter: \s*$/); input('query').enter('nexus'); expect(element('#status').text()).toMatch(/Current filter: nexus\s*$/); //alternative version of the last assertion that tests just the value of the bind using('#status').expect(binding('query')).toBe('nexus'); }); 刷新浏览器,端到端测试器会报告测试失败。为了让测试通过,编辑 index.html ,添加一 个 id为“status” 的 div 或者 p 元素,内容是一个 query 绑定,再加上 Current filter: 前 缀。例如:
Nothing here {{'yet' + '!'}}
这行代码演示了AngularJS模板的核心功能——绑定,这个绑定由双大括号 {{}} 和表达 式 'yet' + '!' 组成。 这个绑定告诉AngularJS需要运算其中的表达式并将结果插入DOM中,接下来的步骤我们将看 到,DOM可以随着表达式运算结果的改变而实时更新。 AngularJS表达式是一种类似于JavaScript的代码片段,AngularJS表达式仅在AngularJS的作用 域中运行,而不是在整个DOM中运行。 引导AngularJS应用 通过ngApp指令来自动引导AngularJS应用是一种简洁的方式,适合大多数情况。在高级开发 中,例如使用脚本装载应用,您可以使用imperative指令或者手动引导AngularJS应用。 AngularJS应用引导过程有3个重要点: 1. 注入器(injector)将用于创建此应用程序的依赖注入(dependencyinjection); 2. 注入器将会创建根作用域作为我们应用模型的范围; 3. AngularJS将会链接根作用域中的DOM,从用ngApp标记的HTML标签开始,逐步处理DOM中指令和 绑定。 一旦AngularJS应用引导完毕,它将继续侦听浏览器的HTML触发事件,如鼠标点击事件、按键事 件、HTTP传入响应等改变DOM模型的事件。这类事件一旦发生,AngularJS将会自动检测变化,并 作出相应的处理及更新。 上面这个应用的结构非常简单。该模板包仅含一个指令和一个静态绑定,其中的模型也是空的。 下一步我们尝试稍复杂的应用! 我工作目录中这些文件是干什么的? 上面的应用来自于AngularJS种子项目,我们通常可以使用AngularJS种子项目来创建新项目。种 子项目包括最新的AngularJS代码库、测试库、脚本和一个简单的应用程序示例,它包含了开发一个典 型的web应用程序所需的基本配置。 对于本教程,我们对AngularJS种子项目进行了下列更改: 1. 删除示例应用程序; 2. 添加手机图像到app/img/phones/; 3. 添加手机数据文件(JSON)到app/phones/; 4. 添加Bootstrap文件到app/css/和app/img/。 练习 试试把关于数学运算的新表达式添加到index.html:1 + 2 = {{ 1 + 2 }}
AngularJS中文社区&&AngularJS英文官网&&代码许可The MIT License&&文档许可CC BY 3.0 ©2012AngularJS.cn|PoweredbyWordPress&bbPress|[湘ICP备12011607] 关于angularjs AngularJS中国社区 查看angularjs发表的文章→ 总结 现在让我们转到步骤1,将一些内容添加到web应用程序。 版权声明:中文文档AngularJS中文社区&&英文文档AngularJS官网&&代码许可The MIT License&&文档许可CC BY 3.0 angularjs发表在入门教程分类,标签AngularJS、入门教程。将本文加入收藏夹。 要发表评论,您必须先登录。 AngularJS中文社区&&AngularJS英文官网&&代码许可The MIT License&&文档许可CC BY 3.0 ©2012AngularJS.cn|PoweredbyWordPress&bbPress|[湘ICP备12011607] 关于angularjs AngularJS中国社区 查看angularjs发表的文章→ AngularJS入门教程01:静态模板 发表于2012年9月16日angularjs 为了说明angularJS如何增强了标准HTML,我们先将创建一个静态HTML页面模板,然后把这个 静态HTML页面模板转换成能动态显示的AngularJS模板。 在本步骤中,我们往HTML页面中添加两个手机的基本信息,用以下命令将工作目录重置到步骤 1。 `git checkout -f step-1` 请编辑app/index.html文件,将下面的代码添加到index.html文件中,然后运行该应用查看效 果。 app/index.html- Nexus S
Fast just got faster with Nexus S.
- Motorola XOOM™ with Wi-Fi
The Next, Next Generation tablet.
Total number of phones: 2
总结 本步骤往应用中添加了静态HTML手机列表,现在让我们转到步骤2以了解如何使用AngularJS动 态生成相同的列表。 版权声明:中文文档AngularJS中文社区&&英文文档AngularJS官网&&代码许可The MIT License&&文档许可CC BY 3.0 angularjs发表在入门教程分类,标签AngularJS、入门教程。将本文加入收藏夹。 要发表评论,您必须先登录。 ← 上一篇 下一篇 → 资讯 文档 社区 关于 搜索 注册登录 AngularJS入门教程02:AngularJS模板 发表于2012年9月21日furtherLee 是时候给这些网页来点动态特性了——用AngularJS!我们这里为后面要加入的控制器添加了一 个测试。 一个应用的代码架构有很多种。对于AngularJS应用,我们鼓励使用[模型-视图-控制器(MVC) 模式][]解耦代码和分离关注点。考虑到这一点,我们用AngularJS来为我们的应用添加一些模型、视图 和控制器。 请重置工作目录: git checkout -f step-2 我们的应用现在有了一个包含三部手机的列表。 步骤1和步骤2之间最重要的不同在下面列出。,你可以到GitHub去看完整的差别。 视图和模板 在AngularJS中,一个视图是模型通过HTML模板渲染之后的映射。这意味着,不论模型什么时候 发生变化,AngularJS会实时更新结合点,随之更新视图。 比如,视图组件被AngularJS用下面这个模板构建出来: ...- {{phone.name}}
{{phone.snippet}}
Total number of phones: {{phones.length}}
创建一个新的数据模型属性,并且把它绑定到模板上。例如: $scope.hello = "Hello, World!" 更新你的浏览器,确保显示出来“Hello,World!” 用一个迭代器创建一个简单的表:row number |
---|
{{i}} |
row number |
---|
{{i+1}} |
Search:
- {{phone.name}}
{{phone.snippet}}
Current filter: {{query}}
在端到端测试里面加一条 pause(); 语句,重新跑一遍。你将发现测试器暂停了!这样允许你有机会在 测试运行过程中查看你应用的状态。测试应用是实时的!你可以更换搜索内容来证明。稍有经验你就会 知道,这对于在端到端测试中迅速找到问题是多么的关键。 总结 我们现在添加了全文搜索功能,并且完成一个测试证明了搜索是对的!现在让我们继续到步骤4来 看看给我们的手机应用增加排序功能。 版权声明:中文文档AngularJS中文社区&&英文文档AngularJS官网&&代码许可The MIT License&&文档许可CC BY 3.0 furtherLee发表在入门教程分类,标签AngularJS、furtherLee、入门教程。将本文加入收藏夹。 要发表评论,您必须先登录。 AngularJS入门教程04:双向绑定 发表于2012年9月22日furtherLee 在这一步你会增加一个让用户控制手机列表显示顺序的特性。动态排序可以这样实现,添加一个 新的模型属性,把它和迭代器集成起来,然后让数据绑定完成剩下的事情。 请重置工作目录: git checkout -f step-4 你应该发现除了搜索框之外,你的应用多了一个下来菜单,它可以允许控制电话排列的顺序。 步骤3和步骤4之间最重要的不同在下面列出。你可以在GitHub里看到完整的差别。 模板 app/index.html: Search: Sort by: - {{phone.name}}
{{phone.snippet}}