angular7學習筆記


安裝angular的命令行工具

npm i -g @angular/cli

 

安裝完后執行以下命令創建新項目:

ng new 項目名

 

然后進入項目目錄

cd 項目名

 

啟動開發環境

ng server

 

快速創建組件(並自動在app.module.ts中導入)

ng g c 組件名

 

 

屬性綁定

[屬性名]="表達式"

如果不加[] 那""里面的就會被當前字符串

如[bgColor]="'red'"等同於 bgColor="red"

如果[bgColor]="red" 這樣寫, 那編譯器會找不到red這個變量

 

class綁定

[ngClass]="{xxx: 表達式, ... }" 表達式為真則元素就有xxx這個class

 

style綁定

注意css屬性名是駝峰式

[ngStyle]="{backgroundColor: isRed ? 'red' : 'green'}"

 

條件渲染

*ngIf="表達式" 

*ngIf="表達式; else 元素引用名稱"

<xxx #名稱 >

<div [ngSwitch]="...">
    <div *ngSwitchCase="...">
    </div>
</div>

 

循環渲染

*ngFor="let item of list"

 

注意:同一個元素只能有一個*指令

 

服務類組件

用於封裝可復用的業務邏輯代碼

一般命名為 xxx.service.ts

創建服務:

import { Injectable } from '@angular/core';

@Injectable()
export class HelloService {
    printHello(): void {
        console.log('hello');
    }
}

 

 

在app.module.ts中注冊一個provider:

//引入HelloService 
import {HelloService} from './hello.service';
//在構造函數中進行依賴注入
@NgModule({
    ...
    providers: [HelloService],
    ...
})

 

 

在需要用到的頁面引入該服務:

import {HelloService} from './hello.service';

//在構造函數中進行依賴注入
constructor(private helloService: HelloService) {...}

//調用服務組件的方法
this.helloService.printHello();

 

 

  • 服務都是單例的,一旦創建就會被緩存起來 重復使用
  • 服務一旦實例化,將在整個應用的生命周期中存在,可以用來共享數據(下面axios部分有實例)
  • 在需要使用服務的地方,利用依賴注入機制注入服務
  • 依賴注入時自定義的服務需要寫在內置的服務后面

父組件 向 子組件 傳數據

<sub-component [propName]="value" >

 

綁定事件監聽

<div (click)="myFunction($event)" >

在組件ts文件內定義myFunction方法,其可接收到$event事件對象

 

自定義事件

<sub-component (myEvent)="doSomething()">

在子組件中,引入EventEmitter,

import {EventEmitter} from "@angular/core";

子組件先聲明事件對象

@Output() myEvent = new EventEmitter<boolean>();

子組件的某個方法里調用

this.myEvent.emit(agreed);


解決跨級組件通信

1 創建服務,new一個EventEmitter

import {Injectable, EventEmitter, OnInit} from "@angular/core";
@Injectable()
export class EmitService implements OnInit {
    public eventEmit: any;

    constructor() {
        // 定義發射事件
        this.eventEmit = new EventEmitter();
    }

    ngOnInit() {

    }
}

2、配置module.ts

import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';

import {AppComponent} from './app.component';
import {EmitComponent} from "./emit.component";
import {EmitService} from "./emit.service";

@NgModule({
    declarations: [
        AppComponent,
        EmitComponent
    ],
    imports: [
        BrowserModule
    ],
    providers: [
        EmitService
    ],
    bootstrap: [
        AppComponent
    ]
})
export class AppModule {
}

3、定義組件,發射消息

import {Component} from '@angular/core';
import {EmitService} from "./emit.service"
@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent {
    constructor(public emitService: EmitService) {

    }

    emitFun() {
        // 如果組件中,修改了某些數據,需要刷新用用戶列表,用戶列表在其他組件中,那么就可以發射一個字符串過去,那邊接收到這個字符串比對一下,刷新列表。
        this.emitService.eventEmit.emit("userList");
    }
}

4、定義接收組件,接收比對發射的字符串,判斷,調取接口,刷新組件內容

import {Component, OnInit} from "@angular/core";
import {EmitService} from "./emit.service"
@Component({
    selector: "event-emit",
    templateUrl: "./emit.component.html"
})
export class EmitComonent implements OnInit {
    constructor(public emitService: EmitService) {

    }

    ngOnInit() {
        // 接收發射過來的數據
        this.emitService.eventEmit.subscribe((value: any) => {
           if(value == "userList") {
               // 這里就可以調取接口,刷新userList列表數據
               alert("收到了,我立馬刷新列表");
           }
        });
    }

}

總結:其實就是EventEmitter的兩個方法,emit(),subscribe()發射和接收;

 

 

 

對象本地指向

(如果是input元素,其類型是HTMLInputElemet)

<div #oneElement > 
<div (click)="func(oneElement)" >
import {ElementRef, ViewChild, ContentChild} from 'angular/core';

//通過 @ViewChild 引用 當前組件模板中的#名稱的dom元素 
@ViewChild('名稱') 變量名: ElementRef

//通過 @ContentChild 引用 父組件中子組件的子元素#名稱的dom元素
@ContentChild('名稱') 變量名: ElementRef

 

 

 

內容分發(類似Vue的slot)

子組件利用<ng-content></ng-content> 引用 父組件中此組件標簽的子元素.

 

生命周期

init之前會調constructor()

ngOnChanges(change: SimpleChanges) ;需要import {SimpleChanges } from '@angular/core';

ngOnInit

ngDoCheck

ngAfterContentInit

ngAfterContentChecked

ngAfterViewInit

ngAfterViewChecked

ngOnDestroy

 

class xxx implements OnInit, OnChanges

 

 

自定義指令

@Directive({
        selector: '[指令名]' })
export class 類名 implements OnInit {
    constructor(private elementRef: ElementRef, renderer: Renderer2) {
         
    }
    ngOnInit() {
    this.renderer.setStyle(this.elementRef.nativeElement, 'background-color', 'red');
  } }

構造函數的參數elementRef就是調用這個指令的元素,前面應該加上private,否則在類中其它方法中引用this.el時會報錯

調用時就是在元素中用上面的指令名做為屬性名, 不需要加[]或*, 

 

使用之前還要在ngModule的declarations中聲明(官方文檔里居然沒有寫這部分)

@ngModule({
    declarations: {
        指令類名
    }
})

我用ionic g d 指令名 這個命令生成的指令, 它自動生成了"directives"文件夾,其下生成了 directives.module.ts 和 "指令名/指令名.directive.ts", directives.module.ts 內容如下:

import { NgModule } from '@angular/core';
import { HightLightDirective } from './hight-light/hight-light';
@NgModule({
    declarations: [HightLightDirective],
    imports: [],
    exports: [HightLightDirective]
})
export class DirectivesModule {}

 

同時,如果使用 directives.module.ts , 那么,在app.module.ts中也可以這樣引用並聲明指令:

import { DirectivesModule } from '../directives/directives.module';

@NgModule({
    ...
    //導入 模塊
    imports: [
        DirectivesModule,
        ...
    ],
    ...
})

 

 

用命令行工具創建指令

ng g d 路徑/my-name

指令文件名小寫以-連接,生成文件名為my-name.directive.ts,

生成的指令類名為MyNameDirectvie, 選擇器名為appMyName,

在指令類中,通過@hostlistener監聽事件

import {HostListener} from '@angular/core';
@HostListener('mouseenter') dosomething(event: Event) {}

 

 

在指令類中,通過@HostBinding綁定屬性,將指令內的變量綁定到引用元素上的屬性值

import {HostBinding} from '@angular/core';
@HostBinding('style.backgroundColor') bgc:strind = 'red';

還可以通過引用元素的屬性向指令傳遞參數,方法與經組件傳參數一樣,用@input()

 

 

 

路由

1.在app-routing.module.ts中引用路由模塊

(*以下代碼,在使用ng new 創建項目時如果選擇了使用路由,那么將會自動創建)

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

 

2.引入組件

在根模塊中引入和聲明組件, (如果是通過命令創建的組件,則工具會自動完成這步)

在app-routing.module.ts中引入組件

import { MyComponent } from "path/to/MyComponent";

 

3.定義路由規則

const routes: Routes = [
    {path: 'path1', component: MyComponent1},
    {path: 'path2', component: MyComponent2},
    ....
];

path如果以/開頭就是絕對路徑,指向網站根路徑,即http://domain/, 否則就是相對路徑,相對於當前 定義路由的模塊的路徑.

比如在 app-routing.module.ts 中定義了一條path: news, 訪問時就是 http://domain/news

*在瀏覽器中訪問時路徑區分大小寫

 

在根組件模板中添加"路由出口",即在HTML中路由動態加載組件的地方

<router-outlet></router-outlet>

 

默認路由

  {path: '**', component: HomeComponent}

  {path: '**', redirectTo: 'home'}

'**'表示匹配任意路徑,(實測發現 '' 也可以)

注意,這個默認路由規則 必須 寫在后面,如果寫在前面,那其它規則就都失效了

 

 

創建跳轉鏈接, 在一個標簽中使用

[routerLink]="[ '/news' ]"

路徑如果是相對路徑,則是相對當前的url,

 

當前激活路由,給他一個類用來指定激活路由的樣式

routerLinkActive="active"

 

路由傳參

get方式

//在html中跳轉連接上加上
[queryParams]="{id:123}"

//跳轉的目標組件引入
import { ActivatedRoute } from '@angular/router';

//目標組件聲明
constructor(public route: ActivatedRoute) {}

//接收參數
this.route.queryParams.subscribe((data)=>{   
console.log(data);
// {id: 123}
})

 

動態路由

//定義路由規則 , 只要在path的值中加入:參數名就可以了
{path: 'home/:id', component: HomeComponent}

//定義連接
[routerLink]="['/path/',  id]"

//目標組件中仍然要引入ActivatedRoute
import {ActivatedRoute} from '@angular/router';

//在構造函數中聲明
constructor(public route: ActivatedRoute) {}

//接收參數,與get傳參唯一不同的是.params
this.route.params.subscribe((data) => {
    console.log(data); //{id: xxx}
});

//官方文檔中是這樣寫的: (paramMap和params有什么區別?)
this.route.paramMap.subscribe(params => {
this.product = products[+params.get('productId')];
});

 

編程方式路由跳轉

在JS代碼中用路由的API進行跳轉, 上面的跳轉都是通過html中添加[routerLink]屬性

編程路由跳轉也分為GET傳值和 動態路由 兩種方式

編程式動態路由跳轉:

//同樣需要在路由規則中配置動態路由規則
{path: 'home/:id', component: HomeComponent}

//在要調用路由跳轉API的組件中引入路由模塊
import {Router} from '@angular/router';

//在構造函數上聲明
contructor(public router: Router) {}

//調用, navigate的第一個參數是一個數組
this.router.navigate(['/path', param]);

//接收
this.route.params.subscribe((data) => {
    console.log('在news頁中接收到',data); // {id: 123}
})

 

 

編程式GET傳參路由跳轉

//引入
import { Router, NavigationExtras } from '@angular/router';


//定義路由參數
let navigationExtras: NavigationExtras = {
    queryParams: {id: 123},
    fragment: 'anchor'
}
this.router.navigate(['/path'], navigationExtras);

//接收
this.route.queryParams.subscribe((data) => {
    console.log('在news頁中接收到',data); // {id: 123}
});

 

 

父子路由/嵌套路由

//在路由規則中定義子中由
const routes: Routes = [
  {
        path: '...',component: ...,
        children: [
    {path: ..., component: ...},
    ...
        ]
    },
]
//跳轉
<a [routerLink]="['/path/to']"  ></a>
//或
<a [routerLink]="['to']"  ></a>
//在父組件中加入 組件模板出口
<router-outlet></router-outlet>

 

HTTP數據請求

GET請求

1.在app.module.ts引入HttpClientModule .

import {HttpClientModule} from '@aunglar/common/http';
imports: [..., HttpClientModule, ...]

2.在用到的地方引入

import {HttpClient} from '@angular/common/http';
並在構造函數聲明
constructor(public http: HttpClient) {}

 

3.使用get請求數據

this.http.get(url).subscribe((response)=>{});

 

POST請求

1.在app.module.ts引入HttpClientModule .與上面一樣(略)

2.在用到的地方引入

import {HttpClient, HttpHeaders} from '@angular/common/http';

 

3.定義http請求選項

const httpOptions = {
    headers: new HttpHeaders({'Content-Type', 'application/json'});
};    

4.調用post請求

this.http.post(url, {...}, httpOptions).subscribe((response)=>{});

 

JSONP請求

1.在app.module.ts引入HttpClientModule 和 HttpClientJsonpModule 

import { HttpClientModule, HttpClientJsonpModule } from '@aunglar/common/http';
imports: [..., HttpClientModule, HttpClientJsonpModule, ...]

 

 2.在用到的地方引用HttpClientModule,(同get請求,略)

並在構造函數聲明

3.使用get請求數據

this.http.jsonp(url, 'callback').subscribe((response)=>{});

注: 第二個參數根據實際服務器的情況設置,可以通過在瀏覽器地址欄直接訪問接口地址,觀察返回結果,如果開頭是callback就寫callback,是什么第二個參數就寫什么

另:http也提供了put,delete 方法

 

使用axios請求數據

安裝

npm i axios -S

 

 

可以新建一個服務, 如果不用服務封裝,也可以直接在使用的組件中直接引入axios並使用

ng g service service/http

 

 

在其中引入

import axios from 'axios';

 

 

調用

axiosGet(url) {
return new Promise((resolve, reject)=>{
    axios.get(url).then((response)
=>{      resolve(response);    });
});
}

 

 

在app.module.ts中引入服務

import httpService from './service/httpservice.service';

 

並在providers中聲明

providers: [..., httpService, ...]

 

 

在使用服務的文件中也要引入服務 (略)

在構造函數的參數中聲明服務對象

constructor(...,public httpService: HttpService) {}

 

 

調用

this.httpService.axiosGet(url).then(...)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM