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}},

];
View Code

 添加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。

 

posted @ 2018-03-06 15:53  Merrys  阅读(492)  评论(0编辑  收藏  举报