服務數據持久化到localStroage生命週期父子組件之間通訊傳值父組件經過@Input給子組件傳值子組件經過ViewChild給父組件傳值子組件經過Output給父組件傳值父子組件相互通訊Rxjs異步數據流編程介紹回調函數事件監聽PromiseRxjs數據交互(Get,Post,jsonp)Get獲取數據Post獲取數據jsonp獲取數據第三方模塊axios獲取數據javascript
建立服務以後,咱們在 StorageService.service.ts 中定義一個測試方法:css
export class StorageService {
constructor() {
}
test() {
alert('調用服務方法');
}
}
複製代碼
咱們從新創建一個 home 組件,來測試服務調用。html
<p>home works!</p>
<button (click)="getService()">獲取服務</button>
複製代碼
import { Component, OnInit } from '@angular/core';
import {StorageService} from '../../services/storage.service';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
constructor(public storage: StorageService) { }
ngOnInit(): void {
}
getService() {
this.storage.test();
}
}
複製代碼
測試:java
以前的 search 和 todoList 測試案例當頁面刷新數據都會消失,接下來咱們在 service 裏構建數據持久化方法(實際是存放到瀏覽器的 localStroage 中)。jquery
首先在 StorageService.service.ts 定義三個方法:ios
set(key: string, value: string[]) {
// @ts-ignore
localStorage.setItem(key, JSON.stringify(value));
}
get(key: string) {
return JSON.parse(localStorage.getItem(key));
}
remove(key: string) {
localStorage.removeItem(key);
}
複製代碼
在組件中調用服務裏定義的方法:git
import {Component, OnInit} from '@angular/core';
import {StorageService} from '../../services/storage.service';
@Component({
selector: 'app-search',
templateUrl: './search.component.html',
styleUrls: ['./search.component.css']
})
export class SearchComponent implements OnInit {
keyWord: any = '';
keyWordsOld: any[] = [];
product: any = '';
products: any[] = [];
constructor(public storage: StorageService) {
}
// 在初始化方法中查詢localStorage中是否有數據
ngOnInit(): void {
// tslint:disable-next-line:prefer-const
let serchList = this.storage.get('serchList');
// tslint:disable-next-line:prefer-const
let todoList = this.storage.get('todoList');
if (serchList) {
// @ts-ignore
this.keyWordsOld = serchList;
}
if (todoList) {
this.products = todoList;
}
}
//輸入內容後回車觸發該方法
keyup(e) {
if (e.keyCode === 13){
//首先判斷搜索內容是否重複,若爲新則加入
if (this.keyWordsOld.indexOf(this.keyWord) === -1) {
this.keyWordsOld.push(this.keyWord);
this.storage.set('serchList', this.keyWordsOld);
}
this.keyWord = '';
}
}
//搜索按鈕綁定的方法
search() {
if (this.keyWordsOld.indexOf(this.keyWord) == -1) {
this.keyWordsOld.push(this.keyWord);
this.storage.set('serchList', this.keyWordsOld);
}
this.keyWord = '';
}
//刪除按鈕綁定的方法
delete(key) {
this.keyWordsOld.splice(key, 1);
this.storage.set('serchList', this.keyWordsOld);
}
//回車事件,觸發該方法
add(e) {
// tslint:disable-next-line:triple-equals
if (e.keyCode == 13) {
if (!this.equalProduct(this.products, this.product)) {
this.products.push({
title: this.product,
status: 0
});
this.product = '';
this.storage.set('todoList', this.products);
} else {
alert('數據已存在');
this.product = '';
}
}
}
deleteWay(key) {
this.products.splice(key, 1);
this.storage.set('todoList', this.products);
}
//新增數據前與已有記錄進行比對
equalProduct(products: any[], value: any) {
if (!value || value === '') {
return false;
}
// tslint:disable-next-line:prefer-for-of
for (let i = 0; i < products.length; i++) {
// tslint:disable-next-line:triple-equals
if (products[i].title == value) {
return true;
}
}
return false;
}
//change事件用來更新緩存中的內容
change() {
this.storage.set('todoList', this.products);
}
}
複製代碼
html 文件基本不變,測試效果:github
注意觀察下方 localStorage 中的內容,當頁面刷新以後數據仍然存在。web
指令和組件的實例有一個生命週期:當 Angular 新建、更新和銷燬它們時觸發。 經過實現一個或多個 Angular core
庫裏定義的生命週期鉤子接口,開發者能夠介入該生命週期中的這些關鍵時刻。npm
每一個接口都有惟一的一個鉤子方法,它們的名字是由接口名再加上 ng
前綴構成的。好比,OnInit
接口的鉤子方法叫作 ngOnInit
, Angular 在建立組件後馬上調用它,:
export class PeekABoo implements OnInit {
constructor(private logger: LoggerService) { }
// implement OnInit's `ngOnInit` method
ngOnInit() { this.logIt(`OnInit`); }
logIt(msg: string) {
this.logger.log(`#${nextId++} ${msg}`);
}
}
複製代碼
生命週期的順序:
這裏咱們重點學習 ngOnInit() 和 ngAfterViewInit()這兩個方法。
首先新建 home 組件,其 html 內容爲:
<h2>這裏一個home組件---DOM操做演示</h2>
<div id="box">
這是一個div標籤
</div>
<br>
<div id="box2" *ngIf="flag" >
這是第二個div標籤
</div>
複製代碼
home.component.ts 文件內容爲:
export class HomeComponent implements OnInit {
flag = true;
constructor() { }
/*生命週期函數*/
ngOnInit(): void {
/*//組件和指令初始化完成,並非真正的dom加載完成*/
let oBox = document.getElementById('box');
console.log(oBox.innerHTML);
oBox.style.color = 'red';
// 此處獲取不到dom節點,因此最好不要在ngOnInit方法中獲取dom節點
/*let oBox2: any = document.getElementById('box2');
console.log(oBox2.innerHTML);
oBox2.style.color = 'blue';*/
}
// 視圖加載完成後觸發的方法,dom加載完成
// tslint:disable-next-line: use-lifecycle-interface
ngAfterViewInit(): void {
let oBox2 = document.getElementById('box2');
console.log(oBox2.innerHTML);
oBox2.style.color = 'blue';
}
}
複製代碼
經過操做 dom 節點來區分 ngOnInit 和 ngAfterViewInit 方法,前者用來初始化指令/組件,後者是當 Angular 初始化完組件視圖及其子視圖以後調用。因此後者才知道 box2 是否渲染完畢,而後才能獲取到該 dom 節點並加以修改。
頁面運行效果以下:
新建四個組件:news,home,header,footer。其中 home 和 header 是父子組件關係,news 和 footer 是父子組件關係 。
一、home.component.html 用來傳遞變量和方法,也能夠將 home 組件中全部信息傳遞過去。
<app-header [msg]="msg" [title]="title" [run]="run" [home]="this"></app-header>
<br>
<hr>
<br>
<h2>我是home組件</h2>
複製代碼
二、home.component.ts
export class HomeComponent implements OnInit {
msg: any = '我是home組件的msg';
title: any = 'home組件的title';
constructor() { }
ngOnInit(): void {
}
run() {
return '執行home組件的run方法';
}
}
複製代碼
三、header.component.html
<h2>我是header組件</h2>
<br>
<p>{{title}}-----{{msg}}</p>
<br>
<button (click)="getParentWay()">執行home組件的方法</button>
複製代碼
四、header.component.ts,子組件中須要引入 Input,用來接收父組件傳過來的數據。
import { Component, OnInit, Input } from '@angular/core';
@Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {
@Input() msg: any;
@Input() title: any;
@Input() run: any;
/*//獲取home組件全部內容*/
@Input() home: any;
constructor() { }
ngOnInit(): void {
}
getParentWay() {
// alert(this.run());
alert(this.home.run());
}
}
複製代碼
五、網頁運行效果以下:
六、小結
父組件給子組件傳值,即子組件獲取父組件的屬性和方法,大體分爲如下幾步:
一、news.component.html,
<app-footer #footerComponent></app-footer>
<br>
<hr>
<br>
<h2>我是news組件</h2>
<button (click)="getChildData()">獲取子組件的數據</button>
<br>
<br>
<br>
<button (click)="getChildWay()">執行子組件的方法</button>
複製代碼
二、news.component.ts
import {Component, OnInit, ViewChild} from '@angular/core';
@Component({
selector: 'app-news',
templateUrl: './news.component.html',
styleUrls: ['./news.component.css']
})
export class NewsComponent implements OnInit {
@ViewChild('footerComponent') footer;
constructor() {
}
ngOnInit(): void {
}
getChildData() {
alert(this.footer.msg);
}
getChildWay() {
this.footer.run();
}
}
複製代碼
三、footer.component.html
<h2>我是footer組件</h2>
複製代碼
四、footer.component.ts
import {Component, OnInit} from '@angular/core';
@Component({
selector: 'app-footer',
templateUrl: './footer.component.html',
styleUrls: ['./footer.component.css']
})
export class FooterComponent implements OnInit {
msg: any = '我是footer組件的msg';
constructor() {
}
ngOnInit(): void {
}
run() {
alert('執行footer組件的run方法');
}
}
複製代碼
五、網頁運行效果以下:
六、小結
子組件給父組件傳值,即父組件主動獲取子組件的屬性和方法,大體分爲如下幾步:
一、news.component.html,
<app-footer (outter)="run($event)"></app-footer>
<br>
<hr>
<br>
<h2>我是news組件</h2>
複製代碼
二、news.component.ts
import {Component, OnInit} from '@angular/core';
@Component({
selector: 'app-news',
templateUrl: './news.component.html',
styleUrls: ['./news.component.css']
})
export class NewsComponent implements OnInit {
constructor() {
}
ngOnInit(): void {
}
run(e) {
console.log(e);
alert('我是news組件的方法');
}
}
複製代碼
三、footer.component.html
<h2>我是footer組件</h2>
<br>
<button (click)="sendMsg()">子組件廣播事務</button>
複製代碼
四、footer.component.ts
import {Component, OnInit, Output, EventEmitter} from '@angular/core';
@Component({
selector: 'app-footer',
templateUrl: './footer.component.html',
styleUrls: ['./footer.component.css']
})
export class FooterComponent implements OnInit {
@Output() private outter = new EventEmitter();
constructor() {
}
ngOnInit(): void {
}
sendMsg() {
this.outter.emit('我是footer組件的數據');
}
}
複製代碼
五、網頁運行效果以下:
六、小結
子組件給父組件傳值,即父組件接收子組件的屬性,大體分爲如下幾步:
子組件 sizer.component.ts:
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-sizer',
templateUrl: './sizer.component.html',
styleUrls: ['./sizer.component.css']
})
export class SizerComponent implements OnInit {
@Input() size: number | string;
@Output() sizeChange = new EventEmitter<number>();
constructor() { }
ngOnInit(): void {
}
inc() {
this.resize(+1);
}
dec() {
this.resize(-1);
}
resize(delta: number) {
this.size = Math.min(40, Math.max(8, +this.size + delta));
this.sizeChange.emit(this.size);
}
}
複製代碼
sizer.component.html:
<h2>子組件</h2>
<div>
<button (click)="dec()" title="smaller">-</button>
<button (click)="inc()" title="bigger">+</button>
<br>
<br>
<label [style.font-size.px]="size">FontSize: {{size}}px</label>
</div>
複製代碼
size
的初始值來自屬性綁定的輸入值。單擊按鈕可在最小值/最大值範圍內增大或減少 size
,而後帶上調整後的大小發出 sizeChange
事件。
Home2Component.fontSize
首先傳遞給 SizerComponent
, $event
變量包含了 SizerComponent.sizeChange
事件的荷載。 當用戶點擊按鈕時,Angular 將 $event
賦值給 Home2Component.fontSizePx
。 父組件 home2.component.html:
<app-sizer [size]="fontSizePx" (sizeChange)="fontSizePx=$event"></app-sizer>
<h2>父組件</h2>
<div [style.font-size.px]="fontSizePx">Resizable Text</div>
複製代碼
Home2Component.fontSizePx
創建初始 SizerComponent.size
值。 home2.component.ts:
fontSizePx = 16;
複製代碼
頁面測試:
上述父子組件之間通訊的關鍵在於:
<app-sizer [size]="fontSizePx" (sizeChange)="fontSizePx=$event"></app-sizer>
複製代碼
此處還能夠經過雙向綁定來實現, 雙向綁定語法其實是屬性綁定和事件綁定的語法糖,因此還能夠改成:
<app-sizer [(size)]="fontSizePx"></app-sizer>
複製代碼
Home2Component.fontSize
被雙向綁定到 SizerComponent
RxJS 是 ReactiveX 編程理念的 JavaScript 版本。ReactiveX 來自微軟,它是一種針對異步數據
流的編程。簡單來講,它將一切數據,包括 HTTP 請求,DOM 事件或者普通數據等包裝成流
的形式,而後用強大豐富的操做符對流進行處理,使你能以同步編程的方式處理異步數據,
並組合不一樣的操做符來輕鬆優雅的實現你所須要的功能。
RxJS 是一種針對異步數據流編程工具,或者叫響應式擴展編程;可無論如何解釋 RxJS 其目
標就是異步編程,Angular 引入 RxJS 爲了就是讓異步可控、更簡單。
RxJS 裏面提供了不少模塊。這裏咱們主要給你們講 RxJS 裏面最經常使用的 Observable 和
fromEvent。
參考手冊:https://www.npmjs.com/package/rxjs
中文手冊:https://cn.rx.js.org/
關於異步編程方法的講解,能夠參考 Javascript異步編程的4種方法。
目前常見的異步編程的幾種方法:
本次測試須要新建一個 home2 組件,和 storage 服務,異步編程方法封裝在 storage 服務中,供組件調用。
首先咱們定義一個同步方法,來測試其效果。
一、storage.service.ts
getData() {
// console.log('this is service data');
return 'this is service data';
}
複製代碼
二、home2.component.ts
import {StorageService} from '../../services/storage.service';
constructor(public storage: StorageService) {
}
/*//一、同步方法*/
getData() {
console.log(this.storage.getData());
}
複製代碼
三、頁面測試
從結果能夠看出,每點擊一下按鈕,同步方法就會馬上獲取到數據。可是在實際生產中,同步操做容易形成堵塞問題,異步操做的出現很好的解決該問題。
這是異步編程最基本的方法。
一、storage.service.ts
// 一秒後獲取數據
getCallbackData(cb) {
setTimeout(() => {
// tslint:disable-next-line:prefer-const
let username = 'hresh';
cb(username);
}, 1000);
}
複製代碼
二、home2.component.ts
import {StorageService} from '../../services/storage.service';
constructor(public storage: StorageService) {
}
getCallbackData() {
/*二、經過Callback獲取異步數據*/
this.storage.getCallbackData((data) => {
console.log(data);
});//a操做
console.log('延時獲取數據');//b操做
}
複製代碼
三、頁面測試
從頁面結果來看,a操做不會阻塞程序運行,會被推遲執行,不會影響b操做的執行。
回調函數的優勢是簡單、容易理解和部署,缺點是不利於代碼的閱讀和維護,各個部分之間高度耦合(Coupling),流程會很混亂,並且每一個任務只能指定一個回調函數。
另外一種思路是採用事件驅動模式。任務的執行不取決於代碼的順序,而取決於某個事件是否發生。
演示代碼以下:
import { Component, OnInit } from '@angular/core';
import * as $ from 'jquery';
@Component({
selector: 'app-home2',
templateUrl: '
<h2>事件監聽</h2>
<input type="button" value="點擊" id="btn">
<input type="button" value="移除" id="del">
'
})
export class Home2Component implements OnInit {
fn1() {
alert('first');
}
fn1() {
alert('first');
}
fn2() {
alert('second');
}
ngOnInit(): void {
$('h2').css('color', 'blue');
let $body = $('body');
$body.delegate('#btn', 'click', this.fn1);
$body.delegate('#btn', 'click', this.fn2);
$('#del').on('done', () => alert('解除事件綁定'));
setTimeout(() => {
$('#del').trigger('done');
}, 2000);
}
}
複製代碼
頁面測試效果:
#btn
標籤能夠綁定多個事件,$('#del').trigger('done')
表示頁面初始化後,2s 以後會觸發 done 事件,從而執行 alert 事件。
這種方法的優勢是比較容易理解,能夠綁定多個事件,每一個事件能夠指定多個回調函數,並且能夠"去耦合"(Decoupling),有利於實現模塊化。缺點是整個程序都要變成事件驅動型,運行流程會變得很不清晰。
Promise 本意是承諾,在程序中的意思就是承諾我過一段時間後會給你一個結果。 何時會用到過一段時間?答案是異步操做,異步是指可能比較長時間纔有結果的才作,例如網絡請求、讀取本地文件等。
它的思想是,每個異步任務返回一個 Promise 對象,該對象有一個 then 方法,容許指定回調函數。好比,f1的回調函數f2,能夠寫成:
f1().then(f2);
複製代碼
在 Angular 項目中可使用以下測試案例:
一、storage.service.ts
getPromiseData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
// tslint:disable-next-line:prefer-const
let username = 'hresh----Promise';
resolve(username);
}, 2000);
});
}
複製代碼
二、home2.component.ts
import {StorageService} from '../../services/storage.service';
constructor(public storage: StorageService) {
}
getPromiseData(){
/*三、經過Promise獲取異步數據*/
let promiseObj = this.storage.getPromiseData();
promiseObj.then((data) => {
console.log(data);
});
}
複製代碼
三、頁面測試
另外 Promise 的 then 方法返回的是一個新的 Promise 實例,所以 then 可用鏈式調用。好比,指定多個回調函數:
f1().then(f2).then(f3);
複製代碼
再好比,指定發生錯誤時的回調函數:
f1().then(f2).fail(f3);
複製代碼
並且,它還有一個前面三種方法都沒有的好處:若是一個任務已經完成,再添加回調函數,該回調函數會當即執行。因此,你不用擔憂是否錯過了某個事件或信號。這種方法的缺點就是編寫和理解,都相對比較難。
Rxjs 處理異步:
一、storage.service.ts
import { Observable } from 'rxjs';
getRxjsData() {
return new Observable((observer) => {
setTimeout(() => {
let uname = 'hresh----Rxjs';
observer.next(uname);
}, 3000);
});
}
複製代碼
二、home2.component.ts
import {StorageService} from '../../services/storage.service';
constructor(public storage: StorageService) {
}
getRxjsData(){
/*四、經過Rxjs獲取異步數據*/
let observer = this.storage.getRxjsData();
let oData = observer.subscribe((data) => {
console.log(data);
});
}
複製代碼
頁面測試效果同 Promise 同樣。從上面列子能夠看到 RxJS 和 Promise 的基本用法很是相似, 除了一些關鍵詞不一樣。 Promise 裏面用的是 then() 和 resolve(),而 RxJS 裏面用的是 next() 和 subscribe()。
其實Rxjs相比Promise 要強大不少。好比 Rxjs 中能夠中途撤回、Rxjs 能夠發射多個值、Rxjs 提供了多種工具函數等等。
Rxjs 能夠經過 unsubscribe() 能夠撤回 subscribe 的動做。
咱們修改 home2.component.ts
文件內容以下:
import {StorageService} from '../../services/storage.service';
constructor(public storage: StorageService) {
}
getRxjsData(){
/*四、經過Rxjs獲取異步數據*/
let observer = this.storage.getRxjsData();
let oData = observer.subscribe((data) => {
console.log(data);
});
/*五、Rxjs容許取消訂閱操做*/
setTimeout(() => {
oData.unsubscribe();
}, 2000);
}
複製代碼
Angular5.x 之後 Get、Post 和 jsonp 經過 HttpClientModule 模塊來和服務器進行數據交互。
一、 在 app.module.ts 中引入 HttpClientModule
import {HttpClientModule} from '@angular/common/http';
imports: [
BrowserModule,
HttpClientModule,
HttpClientJsonpModule
]
複製代碼
二、html 文件內容:
<p>new3 works!</p>
<br>
<hr>
<br>
<button (click)="getData()">get請求數據</button>
<br>
<hr>
<br>
<ul>
<li *ngFor="let item of dataList">{{item.name}} --- {{item.age}}</li>
</ul>
<br>
複製代碼
三、new3.component.ts 文件
import {Component, OnInit} from '@angular/core';
import {HttpClient, HttpHeaders} from '@angular/common/http';
@Component({
selector: 'app-new3',
templateUrl: './new3.component.html',
styleUrls: ['./new3.component.css']
})
export class New3Component implements OnInit {
dataList: any[] = [];
constructor(public client: HttpClient) {
}
ngOnInit(): void {
}
getData() {
// var api = 'http://a.itying.com/api/productlist';
var api = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';
this.client.get(api).subscribe((data: any) => {
console.log(data);
this.dataList = data.members;
});
}
}
複製代碼
四、網頁運行效果以下:
在 SpringMVC 項目構建後臺服務方法,一個是用 RequestBody 接受參數,另外一個是用 RequestParam 接受參數。
@RestController
@CrossOrigin(origins = "http://localhost:4200")
public class EncodingController {
@RequestMapping(value = "/testPostPara2")
public Map testPostPara2(@RequestParam String uname,@RequestParam int age){
Map<String,Object> map = new HashMap<String, Object>();
map.put("name",uname);
map.put("age",age);
return map;
}
@RequestMapping("/testPostBody")
public Map testPostBody(@RequestBody Map<String,Object> objectMap){
System.out.println(objectMap.toString());
return objectMap;
}
}
複製代碼
出於安全緣由,瀏覽器禁止 Ajax 調用駐留在當前原點以外的資源。例如,當你在一個標籤中檢查你的銀行帳戶時,你能夠在另外一個選項卡上擁有 EVILL 網站。來自 EVILL 的腳本不可以對你的銀行 API 作出 Ajax 請求(從你的賬戶中取出錢!)使用您的憑據。 跨源資源共享(CORS)是由大多數瀏覽器實現的W3C規範,容許您靈活地指定什麼樣的跨域請求被受權,而不是使用一些不太安全和不太強大的策略,如IFRAME或JSONP。關於跨域的更多內容能夠參考註解@CrossOrigin解決跨域問題
注意上述方法都返回的是 Map 類型,不須要轉換爲 String 類型返回。可是若是直接訪問 http://localhost:8080/testPostPara2?uname=hresh22&age=24 是會報錯的,必須轉換爲 String 類型。
一、一樣須要在 ap.module.ts 中引入 HttpClientModule 模塊並注入。
二、html
<br>
<button (click)="doPost2()">post提交數據:body中傳參</button>
<br>
<hr>
<br>
<button (click)="doPost()">post提交數據:url後攜帶參數</button>
複製代碼
三、new3.component.ts 文件
import {Component, OnInit} from '@angular/core';
import {HttpClient, HttpHeaders} from '@angular/common/http';
@Component({
selector: 'app-new3',
templateUrl: './new3.component.html',
styleUrls: ['./new3.component.css']
})
export class New3Component implements OnInit {
dataList: any[] = [];
constructor(public client: HttpClient) {
}
ngOnInit(): void {
}
doPost() {
const header = { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) };
let url = 'http://localhost:8080/testPostPara2?uname=hresh22&age=24';
this.client.post(url, {}, header).subscribe((response: any) => {
console.log(response);
});
}
doPost2() {
const header = { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) };
let url = 'http://localhost:8080/testPostBody';
this.client.post(url, { 'uname': 'hresh', 'age': 24 }, header).subscribe((response: any) => {
console.log(response);
});
}
}
複製代碼
四、頁面測試
須要先啓動 web 項目,而後再啓動 Angular 項目,點擊頁面上的按鈕,查看效果。
同 Get 請求獲取數據同樣,而後主要是添加 html 文件和 ts 中的方法。
一、 在 app.module.ts 中引入 HttpClientJsonpModule
import {HttpClientJsonpModule} from '@angular/common/http';
imports: [
BrowserModule,
HttpClientJsonpModule
]
複製代碼
二、html
<button (click)="getJsonpData()">Jsonp獲取數據</button>
複製代碼
三、new3.component.ts 文件
getJsonpData() {
var api = 'http://a.itying.com/api/productlist';
this.client.jsonp(api, 'callback').subscribe((data) => {
console.log(data);
})
}
複製代碼
四、頁面測試
一、安裝 axios
npm install axios
複製代碼
二、配置服務文件 httpservice.service.ts
import {Injectable} from '@angular/core';
import axios from 'axios';
import {Observable} from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class HttpserviceService {
constructor() {
}
//能夠返回Promise對象,也可使用Rxjs,根據我的習慣
axiosGet(api) {
return new Promise((resolve, reject) => {
axios.get(api).then(function(res) {
resolve(res);
});
});
}
axiosRxjs(api) {
return new Observable(function(observer) {
axios.get(api).then(function(res) {
observer.next(res);
});
});
}
}
複製代碼
三、html 文件
<button (click)="getAxiosData()">Axios獲取數據方式一</button>
<hr>
<br>
<button (click)="getAxiosData2()">Axios獲取數據方式二</button>
複製代碼
四、在用到的地方引入 httpservice 並在構造函數聲明
import { HttpserviceService } from '../../services/httpservice.service';
constructor(public client: HttpClient, public httpservice: HttpserviceService) {
}
//經過第三方模塊獲取服務器數據
getAxiosData() {
var api = 'http://a.itying.com/api/productlist';
let axiosObj = this.httpservice.axiosGet(api);
axiosObj.then((data) => {
console.log(data);
})
}
//經過Rxjs獲取
getAxiosData2() {
var api = 'http://a.itying.com/api/productlist';
let axiosObj = this.httpservice.axiosRxjs(api);
axiosObj.subscribe(function (data) {
console.log(data);
})
}
複製代碼
五、頁面測試