首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

AngularJS 与 Angular 的概念对照

Angular 这个名字专指现在和未来的 Angular 版本,而 AngularJS 专指 Angular 的所有 v1.x 版本。

本章提供了一个快速的参考指南,指出一些常用的 AngularJS 语法及其在 Angular 中的等价物。

参见 在线例子 / 下载范例 以学习 Angular 语法

模板基础

模板是 Angular 应用中的门面部分,它是用 HTML 写的。下表中是一些 AngularJS 中的关键模板特性及其在 Angular 中的等价语法。

AngularJS

Angular

绑定/插值表达式content_copyYour favorite hero is: {{vm.favoriteHero}}在 AngularJS 中,花括号中的表达式代表单向绑定。 它把元素的值绑定到了与模板相关控制器的属性上。当使用?controller as?语法时,该绑定需要用控制器的别名(vm)为前缀,这是因为你不得不通过它来指定绑定源。

绑定/插值表达式content_copyYour favorite hero is: {{favoriteHero}}在 Angular 中,花括号中的模板表达式同样代表单向绑定。 它把元素的值绑定到了组件的属性上。 它绑定的上下文变量是隐式的,并且总是关联到组件。 所以,它不需要一个引用变量。要了解更多,请参见模板语法中的插值表达式部分。

过滤器content_copy<td>{{movie.title | uppercase}}</td>要在 AngularJS 中过滤输出,使用管道字符(|)以及一个或多个过滤器。这个例子中把?title?属性过滤成了大写形式。

管道content_copy<td>{{movie.title | uppercase}}</td>在 Angular 中,你使用类似的语法 —— 用管道字符(|)来过滤输出,但是现在直接把它叫做管道了。 很多(但不是所有)AngularJS 中的内置过滤器也成了 Angular 中的内置管道。请参见下面过滤器/管道了解更多信息。

局部变量content_copy<tr ng-repeat="movie in vm.movies"> <td>{{movie.title}}</td> </tr>这里的?movie?是一个用户定义的局部变量

输入变量content_copy<tr *ngFor="let movie of movies"> <td>{{movie.title}}</td> </tr>Angular 有了真正的模板输入变量,它需要使用?let?关键字进行明确定义。要了解更多信息,请参见模板语法中的ngFor 微语法部分。

模板指令

AngularJS 为模板提供了七十多个内置指令。 在 Angular 中,它们很多都已经不需要了,因为 Angular 有了一个更加强大、快捷的绑定系统。 下面是一些 AngularJS 中的关键指令及其在 Angular 中的等价物。

AngularJS

Angular

ng-appcontent_copy<body ng-app="movieHunter">应用的启动过程被称为引导。虽然可以从代码中引导 Angular 应用, 但很多应用都是通过?ng-app?指令进行声明式引导的,只要给它一个应用模块的名字(movieHunter)就可以了。

引导main.tscontent_copyimport { enableProdMode } from '@angular/core'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { AppModule } from './app/app.module'; import { environment } from './environments/environment'; if (environment.production) { enableProdMode(); } platformBrowserDynamic().bootstrapModule(AppModule);app.module.tscontent_copyimport { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { AppComponent } from './app.component'; @NgModule({ imports: [ BrowserModule ], declarations: [ AppComponent ], bootstrap: [ AppComponent ] }) export class AppModule { }Angular 没有引导指令。 总是要通过显式调用一个?bootstrap?函数,并传入应用模块的名字(AppComponent)来启动应用。

ng-classcontent_copy<div ng-class="{active: isActive}"> <div ng-class="{active: isActive, shazam: isImportant}">在 AngularJS 中,ng-class?指令会基于一个表达式来包含/排除某些 CSS 类。该表达式通常是一个“键-值”型的控制对象, 对象中的每一个键代表一个 CSS 类名,每一个值定义为一个返回布尔值的模板表达式。在第一个例子中,如果?isActive?为真,则?active?类被应用到那个元素上。就像第二个例子中所展示的那样,可以同时指定多个类。

ngClasscontent_copy<div [ngClass]="{'active': isActive}"> <div [ngClass]="{'active': isActive, 'shazam': isImportant}"> <div [class.active]="isActive">在 Angular 中,ngClass?指令用类似的方式工作。 它根据一个表达式包含/排除某些 CSS 类。在第一个例子中,如果?isActive?为真,则?active?类被应用到那个元素上。就像第二个例子中所展示的那样,可以同时指定多个类。Angular 还有类绑定,它是单独添加或移除一个类的好办法 —— 就像第三个例子中展示的。要了解更多信息,参见模板语法中的属性、CSS 类和样式绑定部分。

ng-clickcontent_copy<button ng-click="vm.toggleImage()"> <button ng-click="vm.toggleImage($event)">在 AngularJS 中,ng-click?指令指定当元素被点击时的自定义行为。在第一个例子中,如果用户点击了这个按钮,那么控制器的?toggleImage()?方法就会被执行,这个控制器是被?controller as?中指定的?vm?别名所引用的。第二个例子演示了传入?$event?对象,它提供了事件的详情,并被传到控制器。

绑定到?click?事件content_copy<button (click)="toggleImage()"> <button (click)="toggleImage($event)">AngularJS 基于事件的指令在 Angular 中已经不存在了。 不过,可以使用事件绑定来定义从模板视图到组件的单向数据绑定。要使用事件绑定,把目标事件的名字放在圆括号中,并且使用等号右侧引号中的模板语句对它赋值。 然后 Angular 为这个目标时间设置事件处理器。当事件被触发时,这个处理器就会执行模板语句。在第一个例子中,当用户点击此按钮时,相关组件中的?toggleImage()方法就被执行了。第二个例子演示了如何传入?$event?对象,它为组件提供了此事件的详情。要查看 DOM 事件的列表,请参见网络事件。要了解更多,请参见模板语法中的事件绑定部分。

ng-controllercontent_copy<div ng-controller="MovieListCtrl as vm">在 AngularJS 中,ng-controller?指令把控制器附加到视图上。 使用?ng-controller(或把控制器定义为路由的一部分)把视图及其控制器的代码联系在一起。

组件装饰器content_copy@Component({ selector: 'app-movie-list', templateUrl: './movie-list.component.html', styleUrls: [ './movie-list.component.css' ], })在 Angular 中,模板不用再指定它相关的控制器。 反过来,组件会在组件类的装饰器中指定与它相关的模板。要了解更多,请参见架构概览。

ng-hide在 AngularJS 中,ng-hide?指令会基于一个表达式显示或隐藏相关的 HTML 元素。 参见ng-show了解更多。

绑定到?hidden?属性在 Angular 中,并没有一个内置的?hide?指令,可以改用属性绑定。 参见ng-show了解更多。

ng-hrefcontent_copy<a ng-href="{{ angularDocsUrl }}">Angular Docs</a>ng-href?指令允许 AngularJS 对?href?属性进行预处理,以便它能在浏览器获取那个 URL 之前,使用一个返回适当 URL 的绑定表达式替换它。在 AngularJS 中,ng-href?通常用来作为导航的一部分,激活一个路由。content_copy<a ng-href="#{{ moviesHash }}">Movies</a>路由在 Angular 中的处理方式不同。

绑定到?href?属性content_copy<a [href]="angularDocsUrl">Angular Docs</a>在 Angular 中,并没有内置的?href?指令,改用属性绑定。 把元素的?href?属性放在方括号中,并把它设成一个引号中的模板表达式。要了解属性绑定的更多知识,参见模板语法。在 Angular 中,href?不再用作路由,而是改用第三个例子中所展示的?routerLink?指令。content_copy<a [routerLink]="['/movies']">Movies</a>要了解关于路由的更多信息,请参见路由与导航的RouterLink 绑定部分。

ng-ifcontent_copy<table ng-if="movies.length">在 AngularJS 中,ng-if?指令会根据一个表达式来移除或重建 DOM 中的一部分。如果表达式为假,元素就会被从 DOM 中移除。在这个例子中,除非?movies?数组的长度大于 0,否则?<table>?元素就会被从 DOM 中移除。

*ngIfcontent_copy<table *ngIf="movies.length">Angular 中的?*ngIf?指令与 AngularJS 中的?ng-if?指令一样, 它根据表达式的值移除或重建 DOM 中的一部分。在这个例子中,除非?movies?数组的长度大于 0,否则?<table>?元素就会被从 DOM 中移除。在这个例子中?ngIf?前的星号(*)是必须的。 要了解更多信息,参见结构型指令。

ng-modelcontent_copy<input ng-model="vm.favoriteHero"/>在 Angular1 中,ng-model?指令把一个表单控件绑定到了模板相关控制器的一个属性上。 这提供了双向绑定功能,因此,任何对视图中值的改动,都会同步到模型中,对模型的改动,也会同步到视图中。

ngModelcontent_copy<input [(ngModel)]="favoriteHero" />在 Angular 中,双向绑定使用[()]标记出来,它被形象的比作“盒子中的香蕉”。 这种语法是一个简写形式,用来同时定义一个属性绑定(从组件到视图)和一个事件绑定(从视图到组件),就成了双向绑定。要了解使用 ngModel 进行双向绑定的更多知识,参见模板语法中的NgModel—使用?[(ngModel)]?进行双向绑定部分。

ng-repeatcontent_copy<tr ng-repeat="movie in vm.movies">在 Angular1 中,ng-repeat?指令会为指定集合中的每一个条目重复渲染相关的 DOM 元素。在这个例子中,对?movies?集合中的每一个?movie?对象重复渲染了这个表格行元素(<tr>)。

*ngForcontent_copy<tr *ngFor="let movie of movies">Angular 中的?*ngFor?指令类似于 AngularJS 中的?ng-repeat?指令。 它为指定集合中的每一个条目重复渲染了相关的 DOM 元素。 更准确的说,它把被界定出来的元素(这个例子中是?<tr>)及其内容转成了一个模板,并使用那个模板来为列表中的每一个条目实例化一个视图。请注意其它语法上的差异: 在?ngFor?前面的星号(*)是必须的;let?关键字把?movie?标记成一个输入变量;列表中使用的介词是?of,而不再是?in。要了解更多信息,参见结构性指令。

ng-showcontent_copy<h3 ng-show="vm.favoriteHero"> Your favorite hero is: {{vm.favoriteHero}} </h3>在 AngularJS 中,ng-show?指令根据一个表达式来显示或隐藏相关的 DOM 元素。在这个例子中,如果?favoriteHero?变量为真,<div>?元素就会显示出来。

绑定到?hidden?属性content_copy<h3 [hidden]="!favoriteHero"> Your favorite hero is: {{favoriteHero}} </h3>在 Angular 中,并没有内置的?show?指令,可以改用属性绑定。 要隐藏或显示一个元素,绑定到它的?hidden?属性就可以了。要想有条件的显示一个元素,就把该元素的?hidden?属性放到一个方括号里,并且把它设置为引号中的模板表达式,它的结果应该是与显示时相反的值。在这个例子中,如果?favoriteHero?变量不是真值,<div>?元素就会被隐藏。要了解属性绑定的更多知识,参见模板语法中的属性绑定部分。

ng-srccontent_copy<img ng-src="{{movie.imageurl}}">ng-src?指令允许 AngularJS 对?src?属性进行预处理,以便它能够在浏览器获取此 URL 之前,用一个返回适当 URL 的绑定表达式替换它。

绑定到?src?属性content_copy<img [src]="movie.imageurl">在 Angular 中,并没有一个内置的?src?指令,可以使用属性绑定。 把?src?属性放到方括号中,并且把它设为一个引号中的绑定表达式。要了解属性绑定的更多知识,参见模板语法中的属性绑定部分。

ng-stylecontent_copy<div ng-style="{color: colorPreference}">在 AngularJS 中,ng-style?指令根据一个绑定表达式设置一个 HTML 元素的 CSS 样式。 该表达式通常是一个“键-值”形式的控制对象,对象的每个键都是一个 CSS 属性,每个值都是一个能计算为此样式的合适值的表达式。在这个例子中,color?样式被设置为?colorPreference?变量的当前值。

ngStylecontent_copy<div [ngStyle]="{'color': colorPreference}"> <div [style.color]="colorPreference">在 Angular 中,ngStyle?指令的工作方式与此类似。它根据一个表达式设置 HTML 元素上的 CSS 样式。在第一个例子中,color?样式被设置成了?colorPreference?变量的当前值。Angular 还有样式绑定语法,它是单独设置一个样式的好方法。它展示在第二个例子中。要了解样式绑定的更多知识,参见模板语法中的样式绑定部分。要了解关于?ngStyle?指令的更多知识,参见模板语法中的NgStyle部分。

ng-switchcontent_copy<div ng-switch="vm.favoriteHero && vm.checkMovieHero(vm.favoriteHero)"> <div ng-switch-when="true"> Excellent choice! </div> <div ng-switch-when="false"> No movie, sorry! </div> <div ng-switch-default> Please enter your favorite hero. </div></div>在 Angular1 中,ng-switch?指令根据一个表达式的当前值把元素的内容替换成几个模板之一。在这个例子中,如果?favoriteHero?没有设置,则模板显示“Please enter ...”。 如果?favoriteHero?设置过,它就会通过调用一个控制其方法来检查它是否电影里的英雄。 如果该方法返回?true,模板就会显示“Excellent choice!”。 如果该方法返回?false,该模板就会显示“No movie, sorry!”。

ngSwitchcontent_copy<span [ngSwitch]="favoriteHero && checkMovieHero(favoriteHero)"> <p *ngSwitchCase="true"> Excellent choice! </p> <p *ngSwitchCase="false"> No movie, sorry! </p> <p *ngSwitchDefault> Please enter your favorite hero. </p> </span>在 Angular 中,ngSwitch?指令的工作方式与此类似。 它会显示那个与?ngSwitch?表达式的当前值匹配的那个?*ngSwitchCase?所在的元素。在这个例子中,如果?favoriteHero?没有设置,则?ngSwitch?的值是?null,?*ngSwitchDefault?中会显示 “Please enter ...”。 如果设置了?favoriteHero,应用就会通过调用一个组件方法来检查电影英雄。 如果该方法返回?true,就会显示 “Excellent choice!”。 如果该方法返回?false,就会显示 “No movie, sorry!”。在这个例子中,ngSwitchCase?和?ngSwitchDefault?前面的星号(*)是必须的。要了解更多信息,参见模板语法中的NgSwitch 指令部分。

  1. <div ng-switch="vm.favoriteHero &&
  2. vm.checkMovieHero(vm.favoriteHero)">
  3. <div ng-switch-when="true">
  4. Excellent choice!
  5. </div>
  6. <div ng-switch-when="false">
  7. No movie, sorry!
  8. </div>
  9. <div ng-switch-default>
  10. Please enter your favorite hero.
  11. </div>
  12. </div>

在 Angular1 中,ng-switch 指令根据一个表达式的当前值把元素的内容替换成几个模板之一。 在这个例子中,如果 favoriteHero 没有设置,则模板显示“Please enter ...”。 如果 favoriteHero 设置过,它就会通过调用一个控制其方法来检查它是否电影里的英雄。 如果该方法返回 true,模板就会显示“Excellent choice!”。 如果该方法返回 false,该模板就会显示“No movie, sorry!”。ngSwitch content_copy<span [ngSwitch]="favoriteHero && checkMovieHero(favoriteHero)"> <p *ngSwitchCase="true"> Excellent choice! </p> <p *ngSwitchCase="false"> No movie, sorry! </p> <p *ngSwitchDefault> Please enter your favorite hero. </p> </span> 在 Angular 中,ngSwitch 指令的工作方式与此类似。 它会显示那个与 ngSwitch 表达式的当前值匹配的那个 *ngSwitchCase 所在的元素。 在这个例子中,如果 favoriteHero 没有设置,则 ngSwitch 的值是 null*ngSwitchDefault 中会显示 “Please enter ...”。 如果设置了 favoriteHero,应用就会通过调用一个组件方法来检查电影英雄。 如果该方法返回 true,就会显示 “Excellent choice!”。 如果该方法返回 false,就会显示 “No movie, sorry!”。 在这个例子中,ngSwitchCasengSwitchDefault 前面的星号(*)是必须的。 要了解更多信息,参见模板语法中的NgSwitch 指令部分。

过滤器/管道

Angular 中的管道为模板提供了格式化和数据转换功能,类似于 AngularJS 中的过滤器。 AngularJS 中的很多内置过滤器在 Angular 中都有对应的管道。 要了解管道的更多信息,参见Pipes

AngularJS

Angular

currencycontent_copy<td>{{movie.price | currency}}</td>把一个数字格式化成货币。

currencycontent_copy<td>{{movie.price | currency:'USD':true}}</td>Angular 的?currency?管道和 1 中很相似,只是有些参数变化了。

datecontent_copy<td>{{movie.releaseDate | date}}</td>基于要求的格式把日期格式化成字符串。

datecontent_copy<td>{{movie.releaseDate | date}}</td>Angular 的?date?管道和它很相似。

filtercontent_copy<tr ng-repeat="movie in movieList | filter: {title:listFilter}">基于过滤条件从指定的集合中选取出一个子集。

没了在 Angular 中,出于性能的考虑,并没有一个类似的管道。 过滤逻辑应该在组件中用代码实现。 如果它将被复用在几个模板中,可以考虑构建一个自定义管道。

jsoncontent_copy<pre>{{movie | json}}</pre>把一个 JavaScript 对象转换成一个 JSON 字符串。这对调试很有用。

jsoncontent_copy<pre>{{movie | json}}</pre>Angular 的?json?管道做完全相同的事。

limitTocontent_copy<tr ng-repeat="movie in movieList | limitTo:2:0">从集合中选择从(第二参数指定的)起始索引号(0)开始的最多(第一参数指定的)条目数(2)个条目。

slicecontent_copy<tr *ngFor="let movie of movies | slice:0:2">SlicePipe?做同样的事,但是两个参数的顺序是相反的,以便于 JavaScript 中的?slice?方法保持一致。 第一个参数是起始索引号,第二个参数是限制的数量。 和 AngularJS 中一样,如果们改用组件中的代码实现此操作,性能将会提升。

lowercasecontent_copy<td>{{movie.title | lowercase}}</td>把该字符串转成小写形式。

lowercasecontent_copy<td>{{movie.title | lowercase}}</td>Angular 的?lowercase?管道和 1 中的功能完全相同。

numbercontent_copy<td>{{movie.starRating | number}}</td>把数字格式化为文本。

numbercontent_copy<td>{{movie.starRating | number}}</td> <td>{{movie.starRating | number:'1.1-2'}}</td> <td>{{movie.approvalRating | percent: '1.0-2'}}</td>Angular 的?number?管道很相似。 但在指定小数点位置时,它提供了更多的功能,如第二个范例所示。Angular 还有一个?percent?管道,它把一个数组格式化为本地化的(local)百分比格式,如第三个范例所示。

orderBycontent_copy<tr ng-repeat="movie in movieList | orderBy : 'title'">使用表达式中所指定的方式对集合进行排序。 在这个例子中,movieList被根据 movie 的 title 排序了。

没了在 Angular 中,出于性能的考虑,并没有一个类似的管道。 排序逻辑应该在组件中用代码实现。 如果它将被复用在几个模板中,可以考虑构建一个自定义管道。

模块/控制器/组件

无论在 AngularJS 还是 Angular 中,你都要借助“模块”来把应用拆分成一些紧密相关的功能块。

在 AngularJS 中,你要在控制器中写代码,来为视图提供模型和方法。 在 Angular 中,你要创建组件

因为很多 AngularJS 的代码是用 JavaScript 写的,所以在 AngularJS 列显示的是 JavaScript 代码,而 Angular 列显示的是 TypeScript 代码。

AngularJS

Angular

IIFEcontent_copy(function () { ... }());在 AngularJS 中,用立即调用的函数表达式(IIFE)来包裹控制器代码可以让控制器代码不会污染全局命名空间。

没了在 Angular 中不用担心这个问题,因为使用 ES 2015 的模块,模块会替你处理命名空间问题。要了解关于模块的更多信息,参见架构概览中的模块部分。

Angular 模块content_copyangular.module("movieHunter", ["ngRoute"]);在 AngularJS 中,Angular 模块用来对控制器、服务和其它代码进行跟踪。第二个参数定义该模块依赖的其它模块列表。

NgModulescontent_copyimport { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { AppComponent } from './app.component'; @NgModule({ imports: [ BrowserModule ], declarations: [ AppComponent ], bootstrap: [ AppComponent ] }) export class AppModule { }Angular 的模块用?NgModule?装饰器进行定义,有如下用途:imports: 指定当前模块依赖的其它模块列表declaration: 用于记录组件、管道和指令。要了解关于模块的更多知识,参见NgModules。

控制器注册content_copyangular .module("movieHunter") .controller("MovieListCtrl", ["movieService", MovieListCtrl]);在 AngularJS 中,在每个控制器中都有一些代码,用于找到合适的 Angular 模块并把该控制器注册进去。第一个参数是控制器的名称,第二个参数定义了所有将注入到该控制器的依赖的字符串名称,以及一个到控制器函数的引用。

组件装饰器content_copy@Component({ selector: 'app-movie-list', templateUrl: './movie-list.component.html', styleUrls: [ './movie-list.component.css' ], })Angular 会往组件类上添加了一个装饰器,以提供所需的任何元数据。@Component?装饰器把该类声明为组件,并提供了关于该组件的元数据,比如它的选择器(或标签)和模板。这就是把模板关联到代码的方式,它定义在组件类中。要了解关于组件的更多信息,参见架构概览中的组件部分。

控制器函数content_copyfunction MovieListCtrl(movieService) { }在 Angular1 中,你在控制器函数中编写模型和方法的代码。

组件类content_copyexport class MovieListComponent { }在 Angular 中,你要创建组件类。注意:如果你正在用 TypeScript 写 AngularJS,那么必须用?export?关键字来导出组件类。要了解关于组件的更多信息,参见架构概览中的组件部分。

依赖注入content_copyMovieListCtrl.$inject = ['MovieService']; function MovieListCtrl(movieService) { }在 AngularJS 中,你把所有依赖都作为控制器函数的参数。 这个例子注入了一个?MovieService。为了防止在最小化时出现问题,第一个参数明确告诉 Angular 它应该注入一个?MovieService?的实例。

依赖注入content_copyconstructor(movieService: MovieService) { }在 Angular 中,你要把依赖作为组件构造函数的参数传入。 这个例子注入了一个?MovieService。 即使在最小化之后,第一个参数的 TypeScript 类型也会告诉 Angular 它该注入什么。要了解关于依赖注入的更多信息,参见架构概览中的依赖注入部分。

样式表

样式表让你的应用程序看起来更漂亮。 在 AngularJS 中,你要为整个应用程序指定样式表。 随着应用程序的不断成长,为各个部分指定的样式会被合并,导致无法预计的后果。 在 Angular 中,你仍然要为整个应用程序定义样式,不过现在也可以把样式表封装在特定的组件中。

AngularJS

Angular

Link 标签content_copy<link href="styles.css" rel="stylesheet" />AngularJS 在?index.html?的?head?区使用?link?标签来为应用程序定义样式。

样式配置content_copy"styles": [ "styles.css" ],使用 Angular CLI,你可以在?angular.json?文件中配置全局样式。 也可以把扩展名改为?.scss?来使用 sass。StyleUrls在 Angular 中,你可以在?@Component?的元数据中使用?styles?或?styleUrls?属性来为一个特定的组件定义样式表。content_copystyleUrls: [ './movie-list.component.css' ],这让你可以为各个组件设置合适的样式,而不用担心它被泄漏到程序中的其它部分。

扫码关注腾讯云开发者

领取腾讯云代金券

http://www.vxiaotou.com