06集合-AngularJS基础教程

0. 目录

  • 目录
  • 前言
  • 正文
    • 1 Set up
    • 2 Iteration
    • 3 ng-repeat
    • 4 Object properties
    • 5 index
    • 6 ng-init
    • 7 Uniqueness
      • 71 严格相等
      • 72 track by
    • 8 Callback functions
    • 9 -start and -end
    • 10 结论
  • 声明

1. 前言

AngularJS是为了克服HTML在构建应用上的不足而设计的。HTML是一门很好的为静态文本展示设计的声明式语言,但要构建WEB应用的话它就显得乏力了,所以AngularJS做了一些工作来来解决静态网页技术在构建动态应用上的不足。

AngularJS的初衷是为了简化web APP开发,精髓是简单。但是国内外有很多AngularJS的教程,都着重讲AngularJS的强大之处,从而增加了AngularJS学习的难度,本教程试图用通俗的语言讲解最为基础最为实用的内容,简化学习进程、降低学习难度是本教程的初衷。

本系列教程以翻译Chris SmithAngualr Basics为梗概,融合博主自己的理解,为大家提供一个简单明了的学习教程。

本文为系列教程第6篇集合,翻译自Collections

  1. 引言-Introduction
  2. 基础-Basics
  3. 控制器-Controllers
  4. 作用域-Scopes
  5. 集合-Collections
  6. 模块-Modules
  7. 依赖注入-Dependency Injection
  8. 服务-Services
  9. 过滤器-Filters
  10. 指令-Directives
  11. 指令作用域-Directive Scopes
  12. 路由-Routing
  13. 通信-HTTP
  14. 结论

2.正文

上一章Scope中我们了解到,Angular每次通过ng-controller调用controller构造函数时都会创建一个scope。当然,还有一些其他方式可以创建新的scope,其中最流行的方式就是使用相似对象的集合实现。不像Backbone,Angular没有Collection组件,但它支持相似对象的集合,本章将详述这些。

2.1 Set up

除了从Google Hosted Libraries加载Angular之外,为了让表格和列表好看一些,本章的动态案例还加载了Bootstrap。

<!-- index.html(head) -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.js"></script>

接着,通过ng-app指令加载我们的app模块,为了简单起见,我们使用了app的名称,实际上它不是最好的名称。

<!-- index.html -->
<body ng-app="app">
  <!-- Other examples to be inserted here. -->
</body>

正如前面文章所讲过的那样,为了避免使用modules创建controller,我们需要进行一些简单的设置。

/* module.js */
angular.module(‘app‘, []);
angular.module(‘app‘).config([‘$controllerProvider‘, function($controllerProvider) {
  $controllerProvider.allowGlobals();
}]);

这样,我们就可以进行Angular方面集合、循环等方面的交互探索了。

2.2 Iteration

在普通JS中,如果你要通过for循环遍历集合,你可能需要声明一个local变量来引用当前元素,例如。

/* items.js */
var items = [{name: "Item 1"},{name: "Item 2"}];
for (var i = 0; i < items.length; i++) {
  var item = items[i];
}
document.body.innerHTML = item.name;

结果为: Item 2

虽然你可能相信(希望、盼望、打赌)JS为for循环里每一次迭代存在一个词法作用域,但正如上面案例所示,并不存在(词法作用域)。循环之外item属性可用,可以到 Mozilla’s JavaScript Guide了解更多详情。

Angular可以通过内置的for语句避免这些,为了演示起见,我们在控制器内显示item数组。

/* items-controller.js */
function ItemsController($scope) {
  $scope.items = [
    {name: ‘Item 1‘},
    {name: ‘Item 2‘}
  ];
}

假设item是一个长度位置的集合,我们需要遍历元素展示它的name属性。

2.3 ng-repeat

正如Angular为表达式创建一个顶层Angular scope以避免在JS全局作用域中创建变量一样,内置的ng-repeat指令通过为每次循环的每一次迭代创建一个Angular作用域来避免上面的问题

<!-- ng-repeat.html -->
<ol ng-controller="ItemsController">
  <li ng-repeat="item in items" ng-bind="item.name"></li>
  <li ng-bind="item.name"></li>
</ol>

编译结果为:

1. Item 1

2. Item 2

3.

正如结果所示,ng-repeat循环之外的item属性不可用。

针对循环中的每一个元素,ng-repeat创意建一个具备指定属性的子scope。在本案例中,属性名为item,但是它可以是任何值,您可以尝试修改下,看看会怎么样。

2.4 Object properties

(key, value) in object syntax语法允许我们循环对象的属性。

<!-- ng-repeat-name.html -->
<table class="table table-condensed">
  <tr ng-repeat="(propertyName, propertyValue) in {b: ‘two‘, a: 1.0, c: 3}">
    <td ng-bind="propertyName"></td>
    <td ng-bind="propertyValue"></td>
  </tr>
</table>

编译结果如下图所示。

注意,ng-repeat在执行循环之前使用name对数据进行了排序。

我们给ng-repeat传递的item in items语法看起来挺像list comprehension([列表推导式](http://www.cainiao8.com/python/basic/python_14_list_comprehension.html)),但是不幸的是,他不返回任何值,除了对象成员或右边的数组,让我们试一下。

<!-- ng-repeat-for-keyword.html -->
<ol ng-controller="ItemsController">
  <!-- Invalid code! Syntax error, because ‘for‘ is not supported! -->
  <li ng-repeat="item.name for item in items" ng-bind="item.name"></li>
</ol>

产生了错误,是吧。上面的代码没有正常工作。

真正的list comprehension(列表推导式)允许for关键字从原始列表中返回我们需要的任何值,例如 CoffeeScrip的案例所示

2.5 $index

除了可以持有元素的属性外,ng-repeat还把当前元素的序号作为一个特殊的属性,叫做$index。如果我们想给列表加上序号,就可以使用$index了。

<!-- items-controller.html -->
<div ng-controller="ItemsController">
  <div ng-repeat="item in items">
     {{$index + 1}}. {{item.name}}
  </div>
</div>

编译结果为:

1. Item 1

2. Item 2

让我们尝试下嵌套使用ng-repeat。首先我们创建一个复杂一点的数据模型。

/* items-controller-nested.js */
function ItemsController($scope) {
  $scope.items = [
    {name: ‘Item 1‘,
      items: [
       {name: ‘Nested Item 1.1‘},
       {name: ‘Nested Item 1.2‘}
      ]
    },
    {name: ‘Item 2‘,
      items: [
       {name: ‘Nested Item 2.1‘},
       {name: ‘Nested Item 2.2‘}
      ]
    }
  ];
}

然后,我们通过一个两层循环,把数据显示成有序列表。

<!-- items-controller-nested.html -->
<div ng-controller="ItemsController">
  <ol>
    <li ng-repeat="item in items">
      {{item.name}}
      <ol>
        <li ng-repeat="item in item.items">
          {{item.name}}
        </li>
      </ol>
    </li>
  </ol>
</div>

编译结果为:

  1. Item 1

    1. Nested Item 1.1
    2. Nested Item 1.2
  2. Item 2
    1. Nested Item 2.1
    2. Nested Item 2.2

如果我们需要outline风格的嵌套计数怎么办(貌似1.1,1.2,2.1,2.2)?我们如何保证外层循环的数据不被内层循环的数据覆盖?

2.6 ng-init

你可能还记得,我们可以使用ng-init指令可以初始化scope属性,这个案例我们使用ng-init来重新声明变量,以避免外层数据的覆盖。

<div ng-controller="ItemsController">
  <div ng-repeat="item in items" ng-init="outerCount = $index">
    {{outerCount + 1}}. {{item.name}}
    <div ng-repeat="item in item.items">
       {{outerCount + 1}}.{{$index + 1}}. {{item.name}}
    </div>
  </div>
</div>

编译结果为:

1. Item 1

1.1. Nested Item 1.1

1.2. Nested Item 1.2

2. Item 2

2.1. Nested Item 2.1

2.2. Nested Item 2.2

除了$index之外,ng-repeat给循环的每一次迭代增加了一些逻辑属性,$first, $middle, $last, $even和$odd。你可以使用下面的案例尝试下体会一下。使用ng-class指令给条件为真的列表项设置绿色标签。你能让第一个和第五个设置绿色,其他灰色吗,来试一下吧。

<!-- ng-repeat-middle.html -->
<ol>
  <li ng-repeat="val in [1,2,3,4,5]">
    <span class="label label-default"
          ng-class="{‘label-success‘: $middle}">
      {{val}}
    </span>
  </li>
</ol>

编译结果为下面动图所示。

有没有注意到,我们在使用even和odd时,我们的序号是从0开始编号的。

2.7 Uniqueness

注意,如果在js的严格模式下,ng-repeat需要每一个数据都是唯一的(用严格相等)。

2.7.1 严格相等 ===

下面让我们花点时间研究下严格相等,熟悉的同学可跳过。

<!-- equals-controller.html -->
<table class="table table-condensed">
  <tr>
    <td>1 === 1</td>
    <td>{{1 === 1}}</td>
  </tr>
  <tr>
    <td>‘1‘ === ‘1‘</td>
    <td>{{‘1‘ === ‘1‘}}</td>
  </tr>
  <tr>
    <td>1 === ‘1‘</td>
    <td>{{1 === ‘1‘}}</td>
  </tr>
  <tr>
    <td>{} === {}</td>
    <td>{{ {} === {} }}</td>
  </tr>
  <tr>
    <td>{name: 1} === {name: 1}</td>
    <td>{{ {name: 1} === {name: 1} }}</td>
  </tr>
</table>

因为ng-repeat需要保证数据的唯一性,所以下面的代码会报错。但是,比如我们把[1,2,1]改成[1,2,‘1‘]就没问题了。

<!-- ng-repeat-duplicates.html -->
<ol>
  <!-- Invalid code! Duplicate element error, because ‘1‘ is repeated! -->
  <li ng-repeat="val in [1,2,1]" ng-bind="val"></li>
</ol>

2.7.2 track by

如果你需要解决上面的问题,对不唯一的数据进行ng-repeat,可以使用track by关键字,ng-repeat将会忽略元素的相等检测。

<!-- ng-repeat-track-by.html -->
<ol>
  <li ng-repeat="val in [1,2,1] track by $index" ng-bind="val"></li>
</ol>

编译结果为:

  1. 1
  2. 2
  3. 1

当然,我们应该尽可能地保证数据的唯一性,例如给数据添加一个唯一的id属性等。如果您使用$index,结合的改变可能产生DOM事件问题

2.8 Callback functions

Angular同样可以方便的在控制器里建立对集合对象的引用,我们可以在指令中把集合元素属性传递给一个回调函数,如下代码所示。

我们简单的响应用户交互删除集合中的元素,在控制器中,我们可以定义个回调函数,名字可以随意,最好可以叫做destroy。

/* items-controller-destroy.js */
function ItemsController($scope) {
  $scope.items = [
    {id: 1, name: ‘Item 1‘},
    {id: 2, name: ‘Item 2‘},
    {id: 3, name: ‘Item 3‘},
    {id: 4, name: ‘Item 4‘}
  ];

  $scope.destroy = function(item) {
    var index = $scope.items.indexOf(item);
    $scope.items.splice(index, 1);
  };
}

然后,我们使用ng-click="destroy(item)"来个每一个按钮添加事件处理。

<!-- items-controller-destroy.html -->
<div ng-controller="ItemsController">
  <h4 ng-pluralize count="items.length"
      when="{‘one‘: ‘1 item‘, ‘other‘: ‘{} items‘}">
  </h4>
  <table class="table table-condensed">
    <tr ng-repeat="item in items">
      <td ng-bind="item.name"></td>
      <td>
        <button class="btn btn-xs btn-default" ng-click="destroy(item)">
          destroy
        </button>
      </td>
    </tr>
  </table>
</div>

destroy方法的调用方法是Angular声明式语法的典型特性,另外本案例还是演示了[ng-pluralize](http://docs.ngnice.com/api/ng/directive/ngPluralize)的使用。

2.9 -start and -end

虽然不太常见,但是你也可能需要渲染集合成员的兄弟元素。例如,描述列表,定义列表中的dt、dd等。ng-repeat只针对单一元素,使用-start和-end可以扩展该指令。

<dl ng-controller="ItemsController">
  <dt ng-repeat-start="item in items">name</dt>
  <dd ng-bind="item.name"></dd>
  <dt>price</dt>
  <dd ng-repeat-end ng-bind="item.price"></dd>
</dl>

编译结果为:

name

Item 1

price

name

Item 2

price

这些前后缀不仅仅限于ng-repeat,也可以应用与其他指令上。在自定义指令时,记得不要使用这种前后缀命名指令。

2.10 结论

Angular内置的对集合的支持(ng-repeat)既强大又灵活,可以让我们非常快速的创建经典用户界面、增删改查应用。本章的案例证明了我们可以在不接触Angular内核的情况下实现功能强大的web开发。从这里开始,我们深入探究Angular,研究Angular如何管理组件,下一章,我们来学习Angular自制的模块系统。

3.声明

前端开发whqet,关注前端开发,分享相关资源。csdn专家博客,王海庆希望能对您有所帮助,限于作者水平有限,出错难免,欢迎拍砖!

欢迎任何形式的转载,烦请注明装载,保留本段文字。

本文原文链接,http://blog.csdn.net/whqet/article/details/45047181

欢迎大家访问独立博客http://whqet.github.io

时间: 2024-08-26 14:04:00

06集合-AngularJS基础教程的相关文章

转: angularjs基础教程(~~较通俗)

Angularjs-基础教程(1) 很久没有写过东西了,感觉写东西都不知道从哪里开始了,现在还是先写点技术性的吧,angularjs--我兄弟把它叫成“俺哥啦js” 1.下载 官方网址:https://angularjs.org/ CDN:https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.5/angular.min.js 2.简单介绍使用 1.ng-app   ~~~angularjs的渲染范围 决定了angularjs的作用域

03基础-AngularJS基础教程

0. 目录 目录 前言 正文 1 Set up 2 表达式 3 指令 ng-bind ng-init ng-non-bindable ng-show 4 作用域 双向绑定Two-way binding ng-model 5 总结 声明 1. 前言 AngularJS是为了克服HTML在构建应用上的不足而设计的.HTML是一门很好的为静态文本展示设计的声明式语言,但要构建WEB应用的话它就显得乏力了,所以AngularJS做了一些工作来来解决静态网页技术在构建动态应用上的不足. AngularJS

04控制器-AngularJS基础教程

0. 目录 目录 前言 正文 1 ng-controller 2 构建模型-Constructing the model 3 控制器作为属性名-Controller as propertyName 4 依赖注入-Dependency injection 41 scope 5 模型视图控制器MVC-Model-view-controller 6 函数-Functions 7 回调函数 8 结论 声明 1. 前言 AngularJS是为了克服HTML在构建应用上的不足而设计的.HTML是一门很好的为

07模块化-AngularJS基础教程

0. 目录 目录 前言 正文 1 Why use Angular modules为什么使用模块化 2 创建应用模块-Creating the application module 3 加载应用模块-Loading the application module 4 定义控制器-Defining a controller 5 链式定义-Chaining definitions 6 加载模块-Loading modules 10 结论 声明 1. 前言 AngularJS是为了克服HTML在构建应用上

05作用域-AngularJS基础教程

0. 目录 目录 前言 正文 1 setup 2 scope 3 rootScope 4 Isolation隔离 5 Nesting嵌套 6 Inheritance继承 7 scopewatch 8 scopeapply 9 结论 声明 1. 前言 AngularJS是为了克服HTML在构建应用上的不足而设计的.HTML是一门很好的为静态文本展示设计的声明式语言,但要构建WEB应用的话它就显得乏力了,所以AngularJS做了一些工作来来解决静态网页技术在构建动态应用上的不足. AngularJ

python基础教程_学习笔记19:标准库:一些最爱——集合、堆和双端队列

标准库:一些最爱 集合.堆和双端队列 集合 集合Set类位于sets模块中. >>> range(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> set(range(10)) set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) 集合是由序列(或其他可迭代的对象)构建的.主要用于检查成员资格,因此,副本是被忽略的: >>> range(10)*2 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9

SQL基础教程(第2版)第7章 集合运算:7-2 联结(以列为单位对表进行联结)

7-2 联结(以列为单位对表进行联结) ■外联结——OUTER JOIN■ 3张以上的表的联结■交叉联结——CROSS JOIN■联结的特定语法和过时语法 ● 联结( JOIN)就是将其他表中的列添加过来,进行“添加列”的集合运算.UNION是以行(纵向)为单位进行操作,而联结则是以列(横向)为单位进行的. ● 请大家一定要使用标准SQL的语法格式来写联结运算,对于那些过时的或者特定SQL中的写法,了解一下即可,不建议使用. ■什么是联结 ■内联结——INNER JOIN 首先我们来学习内联结(

SQL Server2012 T-SQL基础教程--读书笔记(5-7章)

SQL Server2012 T-SQL基础教程--读书笔记(5-7章) SqlServer T-SQL 示例数据库:点我 Chapter 05 表表达式 5.1 派生表 5.1.1 分配列别名 5.1.2 使用参数 5.1.3 嵌套 5.1.4 多个引用 5.2 公用表表达式 5.2.1 分别列别名 5.2.2 使用参数 5.2.3 定义多个CTE 5.2.4 CTE的多次引用 5.2.5 递归CTE 5.3 视图 5.3.1 视图和ORDER BY 子句 5.3.2 视图选项 5.4 内嵌表

SQL Server2012 T-SQL基础教程--读书笔记

SQL Server2012 T-SQL基础教程--读书笔记 SqlServer Chapter 01 T-SQL 查询和编程背景 1.3 创建表和定义数据的完整性 1.3.1 创建表 1.3.2 定义数据的完整性 1. 主键约束 2. 唯一约束 3. 外键束约 4. CHECK约束 5. 默认约束 Chapter 02 单表查询 2.1 SELECT 语句元素 2.1.7 TOP和OFFSET-FETCH 1. TOP筛选 2. OFFSET-FETCH 2.1.8 开窗函数速览 2.2 谓词