Angular 排序是一种常用的数据处理方式,它可以将数据按照特定的顺序进行排列。Angular 排序可以帮助我们快速地对数据进行分类和排序,以便于我们能够快速地找到所需要的信息。
Angular 排序有很多不同的方法,其中最常用的是冒泡排序、快速排序、归并排序和希尔排序。冒泡排序是一种简单的比较两个元素大小的方法,它会将最大的元素“冒”到最后面;快速排序是一种分而治之的思想,它会将数组分成两部分;归并排序是一种将两个已经有序的子数组合并成一个新的有序数组的方法;而希尔排序是一种将大量元素进行交叉交错式地进行交叉交错式地进行重新拆分划分来达到目标。
// 冒泡排序 function bubbleSort(arr) { for (let i = 0; i < arr.length; i++) { for (let j = 0; j < arr.length - 1 - i; j++) { if (arr[j] > arr[j + 1]) { let temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } return arr; } // 快速排序 function quickSort(arr) { if (arr.length <= 1) return arr; let pivotIndex = Math.floor(arr.length / 2); let pivot = arr.splice(pivotIndex, 1)[0]; let leftArr = []; let rightArr = []; for (let i = 0; i < arr.length; i++) { if (arr[i] < pivot) { leftArr.push(arr[i]); } else { rightArr.push(arr[i]); } } return quickSort(leftArr).concat([pivot], quickSort(rightArr)); // 通过 concat() 方法来合并三部分内容 // 左边、中间、右边 // 然后再不断地对左右两部分进行快速拆解 // 直至所有内容都被正确地“划分”出来 // 最后再将所有内容“合并”起来即可得出正确的顺序
对下列概念有基本的理解:
到目前为止,我们已经学过了单个 HTML 元素的简单动画。Angular 还允许你在进入和离开页面时播放 "动画协调序列",比如当整个网格或元素列表进入或离开页面时,多个条目的动画之间需要彼此协调时间。你可以选择并行执行多个动画,或者按顺序逐个运行离散动画。
用来控制复杂动画序列的函数如下:
函数 |
详情 |
---|---|
query()
|
用于查找一个或多个内部 HTML 元素。 |
stagger()
|
用于为多元素动画应用级联延迟。 |
group() |
用于并行执行多个动画步骤。 |
sequence()
|
用于逐个顺序执行多个动画步骤。 |
大多数复杂动画都依赖 query()
函数来查找子元素并对其应用动画,基本的例子是:
例子 |
详情 |
---|---|
|
用于查询简单的 HTML 元素并直接对它们应用动画。 |
|
用于查询子元素,这些元素本身就应用了动画元数据并触发这样的动画(否则将被当前/父元素的动画阻止)。 |
query()
的第一个参数是一个 css 选择器字符串,它还可以包含以下 Angular 特定的标记:
标记 |
详情 |
---|---|
|
用于进入/离开元素。 |
:animating
|
对于当前正在播放动画的元素。 |
@*
@triggerName
|
对于具有任何(或特定)触发器的元素。 |
:self
|
动画元素本身。 |
进入和离开元素
并非所有子元素都会实际上被认为是进入/离开;有时,这可能是违反直觉和令人困惑的。
你还可以在 Querying 选项卡下的动画实时示例(在动画介绍部分)中看到这方面的插图。
通过 query()
查询子元素后,stagger()
函数允许你定义每个查询的动画项之间的时间间隙,从而为元素之间延迟设置动画。
下面的例子演示了如何使用 query()
和 stagger()
函数对依次添加的英雄列表从上到下播放动画(有少许延迟)。
query()
查阅正在进入或离开页面的任意元素。该查询会找出那些符合某种匹配 CSS 选择器的元素
style()
为其设置初始样式。使其变得透明,并使用 transform
将其移出位置,以便它能滑入后就位。
stagger()
来在每个动画之间延迟 30 毫秒
animations: [
trigger("pageAnimations", [
transition(":enter", [
query(".hero", [
style({opacity: 0, transform: "translateY(-100px)"}),
stagger(30, [
animate("500ms cubic-bezier(0.35, 0, 0.25, 1)",
style({ opacity: 1, transform: "none" }))
])
])
])
]),
你已经了解了如何在两个连续的动画之间添加延迟。不过你可能还想配置一些并行的动画。比如,你可能希望为同一个元素的两个 CSS 属性设置动画,但要为每个属性使用不同的 easing
函数。这时,你可以使用动画函数 group()
。
注意:
group()
函数用于对动画步骤进行分组,而不是针对动画元素。
在下面的例子中,对 :enter
和 :leave
使用分组,可以配置两种不同的时序。它们会同时作用于同一个元素,但彼此独立运行。
animations: [
trigger("flyInOut", [
state("in", style({
width: "*",
transform: "translateX(0)", opacity: 1
})),
transition(":enter", [
style({ width: 10, transform: "translateX(50px)", opacity: 0 }),
group([
animate("0.3s 0.1s ease", style({
transform: "translateX(0)",
width: "*"
})),
animate("0.3s ease", style({
opacity: 1
}))
])
]),
transition(":leave", [
group([
animate("0.3s ease", style({
transform: "translateX(50px)",
width: 10
})),
animate("0.3s 0.2s ease", style({
opacity: 0
}))
])
])
])
]
复杂动画中可以同时发生很多事情。但是当你要创建一个需要让几个子动画逐个执行的动画时,该怎么办呢?以前我们使用 group()
来同时并行运行多个动画。
第二个名叫 sequence()
的函数会让你一个接一个地运行这些动画。在 sequence()
中,这些动画步骤由 style()
或 animate()
的函数调用组成。
style()
用来立即应用所指定的样式数据。
animate()
用来在一定的时间间隔内应用样式数据。来看看范例应用中的另一个动画。在 Filter/Stagger 页,往 Search Heroes 文本框中输入一些文本,比如 Magnet
或 tornado
。
过滤器会在你输入时实时工作。每当你键入一个新字母时,就会有一些元素离开页面,并且过滤条件也会逐渐变得更加严格。相反,当你删除过滤器中的每个字母时,英雄列表也会逐渐重新进入页面中。
HTML 模板中包含一个名叫 filterAnimation
的触发器。
<label for="search">Search heroes: </label>
<input type="text" id="search" #criteria
(input)="updateCriteria(criteria.value)"
placeholder="Search heroes">
<ul class="heroes" [@filterAnimation]="heroesTotal">
<li *ngFor="let hero of heroes" class="hero">
<div class="inner">
<span class="badge">{{ hero.id }}</span>
<span class="name">{{ hero.name }}</span>
</div>
</li>
</ul>
该组件装饰器中的 filterAnimation
包含三个转场。
@Component({
animations: [
trigger("filterAnimation", [
transition(":enter, * => 0, * => -1", []),
transition(":increment", [
query(":enter", [
style({ opacity: 0, width: 0 }),
stagger(50, [
animate("300ms ease-out", style({ opacity: 1, width: "*" })),
]),
], { optional: true })
]),
transition(":decrement", [
query(":leave", [
stagger(50, [
animate("300ms ease-out", style({ opacity: 0, width: 0 })),
]),
])
]),
]),
]
})
export class HeroListPageComponent implements OnInit {
heroesTotal = -1;
get heroes() { return this._heroes; }
private _heroes: Hero[] = [];
ngOnInit() {
this._heroes = HEROES;
}
updateCriteria(criteria: string) {
criteria = criteria ? criteria.trim() : "";
this._heroes = HEROES.filter(hero => hero.name.toLowerCase().includes(criteria.toLowerCase()));
const newTotal = this.heroes.length;
if (this.heroesTotal !== newTotal) {
this.heroesTotal = newTotal;
} else if (!criteria) {
this.heroesTotal = -1;
}
}
}
这个例子中的代码包含下列任务:
对于每次匹配:
尽管 Angular 开箱即用的支持 *ngFor
列表项动画,但如果只是它们的顺序变化了,就无法支持。因为 Angular 会忘记哪个元素是哪个元素,从而导致这些动画被破坏。帮助 Angular 跟踪此类元素的唯一方法是将 TrackByFunction
分配给 NgForOf
指令。这可确保 Angular 始终知道哪个元素是哪个,从而允许它始终将正确的动画应用于正确的元素。
重要:
如果你需要为 *ngFor
列表的条目设置动画,并且此类条目的顺序有可能在运行时更改,请始终使用 TrackByFunction
。
Angular 中这些用于多元素动画的函数,都要从 query()
开始,查找出内部元素,比如找出某个 <div>
中的所有图片。其余函数 stagger()
、group()
和 sequence()
会以级联方式或你的自定义逻辑来控制要如何应用多个动画步骤。
生产环境下的ServiceWorker本页讲的是如何使用AngularServiceWorker发布和支持生产环境下的应用。它解释了AngularServiceWorker...
安全本主题会讲述Angular为防范Web应用常见的安全漏洞和攻击(比如跨站脚本攻击)内置的保护措施,但不会涉及应用级安全,比如用...
Angular编译器选项使用AoT编译时,可以通过在TypeScript配置文件中指定模板编译器选项来控制如何编译应用程序。模板选项对象an...
AngularJS v1.5 简明教程中文版本文是 樊潇洁 翻译的最新版本(v1.5版)的AngularJS教程。官方英文版请见AngularJS 官方教程和An...
AngularJS ng-change 指令 AngularJS 参考手册AngularJS 实例当输入框的值改变时执行函数:body ng-app="myApp"div ng-controller...
AngularJS ng-click 指令 AngularJS 参考手册AngularJS 实例按钮每次点击时,计数变量 count 自动加 1: button ng-click="count ...
AngularJS ng-dblclick 指令 AngularJS 参考手册AngularJS 实例在每次鼠标双击时,变量 count 加 1:h1 ng-dblclick="count = cou...
AngularJS ng-href 指令 AngularJS 参考手册AngularJS 实例使用 AngularJS 设置添加链接:div ng-init="myVar = 'http://www....
AngularJS ng-mouseover 指令 AngularJS 参考手册AngularJS 实例在鼠标指针移动到元素上时执行表达式:div ng-mouseover="count ...