Angular CLI 簡單使用
版本5.2.7
全局安裝脚手架
npm install -g @angular/cli
新建一個項目
ng new ng-app
啓動項目
ng serve -o
新建一個組件
ng g component heroes
輸入框雙向綁定
X.component.html
<div>
<label>name:
<input [(ngModel)]="hero.name" placeholder="name">
</label>
</div>
[(ngModel)]
是一个Angular语法,用与把hero.name
绑定到输入框中。 它的数据流是双向的:从属性到输入框,并且从输入框回到属性。
app.module.ts
import { FormsModule } from '@angular/forms'; imports: [ BrowserModule, + FormsModule ],
循環列表
*ngFor="let data of datas"
判斷顯示
*ngIf="X"
添加事件
(click)="handle(arg)"
樣式判定
[class.selected]="X=== selectedX"
模擬獲取數據
ng generate service name --module=app
name.service.ts
+ import {Hero} from './hero/hero'; + import {HEROES} from './mock'; export class HeroService { + getHeroes(): Hero[] { + return HEROES; + } }
where you use:
+ import {HeroService} from '../hero.service'; constructor( + private heroService: HeroService ) {}
添加路由
look at index.html
<base href="/">
The router needs this to define where the root of our application is.
ng g module app-routing --flat --module=app
ng g component test
ng g component test-child
app-routing.module 引入模块时使用相对路径(./)
+import {RouterModule, Routes} from '@angular/router'; +import {TestComponent} from './test/test.component'; +import {TestChildComponent} from './test-child/test-child.component'; +const child: Routes = [ + {path: '', component: TestComponent}, + {path: 'test-child', component: TestChildComponent}, +]; +const routes: Routes = [ + { + path: 'test', + children: child + } +]; @NgModule({ imports: [ + RouterModule.forRoot(routes), + RouterModule.forChild(child)], + exports: [RouterModule], })
test.component.html
<p>
test works!
<a routerLink="test-child">to test-child</a>
</p>
test-child.component.html
<p>
test-child works!
</p>
添加路由傳參
使用官網介紹的HeroList
name.service.ts
+ getHero(id: number): Hero { + return HEROES.find(hero => hero.id === id); + }
app-routing.module
+import {HeroesComponent} from './heroes/heroes.component'; +import {HeroComponent} from './hero/hero.component';
const routes: Routes = [
+ {path: 'heroes', component: HeroesComponent},
+ {path: 'hero/:id', component: HeroComponent}
];
heroes.component.html
<div> <ul> <li *ngFor="let hero of heroes" [class.seleted]="hero === selectedHero"> <a routerLink="/hero/{{hero.id}}"><span>{{hero.id}}</span><span>{{hero.name}}</span></a> </li> </ul> </div>
hero.component
import {ActivatedRoute} from '@angular/router'; +import {Hero} from './hero'; +import {HeroService} from '../hero.service'; export class HeroComponent implements OnInit { + hero: Hero; + id: number; constructor( + private heroService: HeroService, + private route: ActivatedRoute) { } ngOnInit() { + this.route.params + .subscribe(x => { + this.hero = this.heroService.getHero(+x.id); + }); } }
給路由添加data屬性
const child: Routes = [
{path: '', redirectTo: 'test', pathMatch: 'full'},
{path: 'test/test-child', component: TestChildComponent, data: {navigation: false}}, ]; const routes: Routes = [ {path: 'heroes', component: HeroesComponent, data: {navigation: true}}, { path: 'test', data: {navigation: true}, children: child }, {path: 'hero/:id', component: HeroComponent, data: {navigation: true}} ];
用來判斷是否顯示導航,或是做页面访问权限判断。----开玩笑,我也不知道什么情景有用
app.component
import {Router, ActivatedRoute, NavigationEnd} from '@angular/router'; navigation: string; constructor(private router: Router, private activatedRoute: ActivatedRoute) { } getNavigation(): void { this.router.events .subscribe((event) => { if (event instanceof NavigationEnd) { this.navigation = this.activatedRoute.firstChild.routeConfig.data.navigation; } }); } ngOnInit() { this.getNavigation(); }
<ul *ngIf="navigation">
<li routerLink="test">test</li>
<li routerLink="heroes">heroes</li>
</ul>
終版
const child: Routes = [ {path: '', redirectTo: 'test', pathMatch: 'full'}, {path: 'test/test-child', component: TestChildComponent, data: {navigation: false}}, {path: 'test/test-child2', component: TestChild2Component, data: {navigation: true}}, ]; const routes: Routes = [ {path: '', redirectTo: 'heroes', pathMatch: 'full'}, { path: 'test', data: {navigation: true}, component: TestComponent, pathMatch: 'full', children: child }, {path: 'heroes', component: HeroesComponent, data: {navigation: true}}, {path: 'hero/:id', component: HeroComponent, data: {navigation: true}}, ];
添加http
app.module.ts
+ import {HttpClientModule} from '@angular/common/http'; imports: [ BrowserModule, FormsModule, AppRoutingModule, + HttpClientModule ],
hero.service.ts
+ import {HttpClient} from '@angular/common/http';
private heroesUrl = 'http://127.0.0.1:8080/getName';
getHeroes2(): Observable<any> { return this.http.get<any>(this.heroesUrl + '?name=user_name'); } getHeroes3(): Observable<any> { return this.http.post<any>(this.heroesUrl,{name:"user_name"}); }
服務器是用nodejs起的,用的以前寫過的數據,調用接口和本地模擬的時候是一樣的。
初步看到這裏了,得先看看typescript和rxjs才好繼續。
附上github地址,純新互勉。
添加父子間的數據傳遞
父傳子:heroes組建中將hero傳遞給<app-hero [hero]="selectedHero"></app-hero>
子傳父:
子組件
import {Component, OnInit, Input, Output, EventEmitter} from '@angular/core'; @Component({ selector: 'app-sizes-child', templateUrl: './sizes-child.component.html', styleUrls: ['./sizes-child.component.css'] }) export class SizesChildComponent implements OnInit { @Input() size: number | string; @Output() changeSize = new EventEmitter<number | string>(); constructor() { } changedSize(size:number | string):void{ this.changeSize.emit(size) } ngOnInit() { } }
<p>
ngModel:雙向綁定
ngModelChange:傳遞子數據
{{size}}
<input [(ngModel)]="size" (ngModelChange)="changedSize($event)">
</p>
父組件
<app-sizes-child [size]="fontSizePx" (changeSize)="handleSize($event)"></app-sizes-child> changedSize:{{changedSize}}
import {Component, OnInit} from '@angular/core'; @Component({ selector: 'app-sizes', templateUrl: './sizes.component.html', styleUrls: ['./sizes.component.css'] }) export class SizesComponent implements OnInit { fontSizePx: number | string = '20'; changedSize: number | string; constructor() { } handleSize($event) { this.changedSize = $event; } ngOnInit() { } }
總結:vue,react,angular,師出同門,相煎何太急。
添加动画
import {Component, OnInit} from '@angular/core'; import {trigger, state, style, animate, transition} from '@angular/animations'; @Component({ selector: 'app-animations', templateUrl: './animations.component.html', styleUrls: ['./animations.component.css'], animations: [ trigger('signal', [ state('hide', style({ 'height': 0, 'background-color': 'green' })), state('show', style({ 'height': '100px', 'background-color': 'yellow' })), transition('*=>*', animate(500)) ]) ] }) export class AnimationsComponent implements OnInit { signal: string; constructor() { } hide() { this.signal = 'hide'; } show() { this.signal = 'show'; }
toggleState() { this.signal= this.signal=== 'hide' ? 'show' : 'hide'; }
ngOnInit() { } }
<div [@signal]="signal"></div> <button (click)="hide()">hide</button> <button (click)="show()">show</button>
在适用的元素上绑定[@trigger],每当state改变,触发相应animation。