原则:
- 多人协作,逐步升级,采用ngUpgrade, 兼容Angularjs和Angular
- 一个文件,一个组件,控制器、service、template划分清晰
- 引入ts进行类型校验
- 逻辑功能划分清晰
- 使用webpack等构件工具,进行依赖管理
思路:
- 使用 ngUpgrade 时,你实际上在同时运行 AngularJS 和 Angular。
- 所有 Angular 的代码运行在 Angular 框架中,而 AngularJS 的代码运行在 AngularJS 框架中。
- 所有这些都是真实的、全功能的框架版本。 没有进行任何仿真
案例:
- NgModule,可以嵌套,但是只有一个Root NgModule。
- 采用注解@NgModule
-
NgModule,可以理解为功能模块
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; // @NgModule decorator with its metadata @NgModule({ declarations: [AppComponent], imports: [BrowserModule], providers: [], bootstrap: [AppComponent] }) export class AppModule {}
- Component,可以理解为一个视图、相关业务逻辑的封装,采用@Component添加元数据。
@Component({
selector: 'app-hero-list',
templateUrl: './hero-list.component.html',
providers: [ HeroService ]
})
export class HeroListComponent implements OnInit {
/* . . . */
}
- 组件可复用,但是不拘泥于同一个NgModule。不同的NgModule之间,也可以复用Component组件。
- 一个Component,对应一个HTML页面。html页面,中可以清晰的观察到组件之间的视图层次结构关系。
- 组件视图修改,除了常用的指令、事件触发修改外,还可以通过管道提前修改。
-
组件,HTML模板中,不可放入script。因为会被自动转义。
-
HTML attribute vs. DOM property
- attribute 作用于html 初始化
- property 作用于数据修改,初始化的attribute不会修改,也就是使用这种语法 [src] = 'src '
-
父子组件通信 - 传递数据给子组件@Input
import { Component, Input } from '@angular/core'; // First, import Input
export class ItemDetailComponent {
@Input() item: string; // decorate the property with @Input()
}
<p>
Today's item: {{item}}
</p>
<app-item-detail [item]="currentItem"></app-item-detail>
export class AppComponent {
currentItem = 'Television';
}
- 父子组件通信 - 传递数据给父组件@Output, 与vue 类似,子组件发射事件,父组件监听事件
import { Output, EventEmitter } from '@angular/core';
export class ItemOutputComponent {
@Output() newItemEvent = new EventEmitter<string>();
addNewItem(value: string) {
this.newItemEvent.emit(value);
}
}
<label>Add an item: <input #newItem></label>
<button (click)="addNewItem(newItem.value)">Add to parent's list</button>
export class AppComponent {
items = ['item1', 'item2', 'item3', 'item4'];
addItem(newItem: string) {
this.items.push(newItem);
}
}
<app-item-output (newItemEvent)="addItem($event)"></app-item-output>
<ul>
<li *ngFor="let item of items">{{item}}</li>
</ul>
- 循环
<app-item-detail *ngFor="let item of items" [item]="item"></app-item-detail>
<div *ngFor="let item of items; let i=index">{{i + 1}} - {{item.name}}</div>
<div *ngFor="let item of items; trackBy: trackByItems">
({{item.id}}) {{item.name}}
</div>
trackByItems(index: number, item: Item): number { return item.id; }
- switch
<div [ngSwitch]="currentItem.feature">
<app-stout-item *ngSwitchCase="'stout'" [item]="currentItem"></app-stout-item>
<app-device-item *ngSwitchCase="'slim'" [item]="currentItem"></app-device-item>
<app-lost-item *ngSwitchCase="'vintage'" [item]="currentItem"></app-lost-item>
<app-best-item *ngSwitchCase="'bright'" [item]="currentItem"></app-best-item>
<app-unknown-item *ngSwitchDefault [item]="currentItem"></app-unknown-item>
</div>
- 取值
<p>The item name is: {{item?.name}}</p>
<p *ngIf="item">The item's color is: {{item!.color}}</p> --! 来告诉类型检查器不要抛出错误
- [] 、() 使用场景:
- []
<img [src]="heroImageUrl"> <app-hero-detail [hero]="currentHero"></app-hero-detail> // 组件属性 <div [ngClass]="{'special': isSpecial}"></div> <button [attr.aria-label]="help">help</button> <div [class.special]="isSpecial">Special</div> <button [style.color]="isSpecial ? 'red' : 'green'">
- []
- ()
<button (click)="onSave()">Save</button>
<app-hero-detail (deleteRequest)="deleteHero()"></app-hero-detail> // 组件事件
<div (myClick)="clicked=$event" clickable>click me</div>
- 操作dom
<input #phone placeholder="phone number" />
<!-- lots of other elements -->
<!-- phone refers to the input element; pass its `value` to an event handler -->
<button (click)="callPhone(phone.value)">Call</button>
<input ref-fax placeholder="fax number" />
<button (click)="callFax(fax.value)">Fax</button>
- 模板语句 ()=statement
<button (click)="onSave($event)">Save</button>
<button *ngFor="let hero of heroes" (click)="deleteHero(hero)">{{hero.name}}</button>
<form #heroForm (ngSubmit)="onSubmit(heroForm)"> ... </form>
- 模板$event对象,模板输入变量(let hero)和模板引用变量(#heroForm)
- 模板语句不能引用全局名称空间中的任何内容。他们无法引用window或document、console.log或Math.max
- 数据绑定
类型 | 语法 | 类别 |
---|---|---|
插值 | {{}} | 单向 |
class、style | [target]="expression" or bind-target="expression" | 单向 |
事件 | (click)="expression" or on-click = "expression" | 单向 |
双向 | [(target)] = "expression" or bindon-target = "expression" | 双向 |
- 模板语法、指令中的不同
Desc | AngularJS | Angular |
---|---|---|
1. module | angular.module | NgModule,其中配置bootstrap标记为root Module |
2.bootstrap | angular.bootstrap | NgModule中属性bootstrap |
3.scope | ng-app | app.module.ts中AppModule默认为根视图 |
4.controller | ngng-controller | @Component等 metadata方式绑定组件、业务逻辑、视图 |
5.数据绑定 | {{user.name}} | {{user.name}} ,支持模板表达式,先计算,在转为字符串展示 |
6.input value | ng-value | [value]= |
7.双向数据绑定 | ng-model | ([ngModel]) = |
8.其余属性绑定 | ng-attr-title="title" | [attr.title]="actionName" or [title] = '' ,动态修改属性 |
9.if | ng-if | *ngIf |
10.for | ng-repeat | *ngFor |
11 | ng-bind | [hero] |
12 | ng-bind-html | [innerHTML]= |
13 | ng-blur | |
14 | ng-change | |
15 | ng-class | [ngClass] |
16 | ng-class-even | |
17 | ng-class-odd | |
18 | ng-click | (click) or on-click |
19 | ng-cloak | |
20 | ng-copy | |
21 | ng-focus | |
22 | ng-keydown | |
23 | ng-keyup | |
24 | ng-mouseenter | |
25 | ng-mouseleave | |
26 | ng-mouseover | |
27 | ng-mousemove | |
28 | ng-required | |
29 | ng-selected | |
30 | ng-show | [class.hidden] or [hidden] |
31 | ng-src | [src] or bind-src , [src]="itemImageUrl"> 与 src="{{itemImageUrl}}" 等效 |
32 | ng-style | *ngStyle 、[style.display] |
33 | ng-disabled | [disabled] |