Angular基礎知識學習(二)

服務數據持久化到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

數據持久化到localStroage

以前的 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({
          titlethis.product,
          status0
        });
        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 是父子組件關係 。

父組件經過@Input給子組件傳值

一、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());
  }

}
複製代碼

五、網頁運行效果以下:

六、小結

父組件給子組件傳值,即子組件獲取父組件的屬性和方法,大體分爲如下幾步:

  1. 父組件頁面嵌套子組件頁面,將屬性和方法存放在子組件聲明中;
  2. 子組件引入 Input 模塊;
  3. 子組件經過@Input 獲取子組件聲明中存放的屬性和方法;

子組件經過ViewChild給父組件傳值

一、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方法');
  }

}
複製代碼

五、網頁運行效果以下:

六、小結

子組件給父組件傳值,即父組件主動獲取子組件的屬性和方法,大體分爲如下幾步:

  1. 父組件頁面嵌套子組件頁面,子組件聲明時須要定義一個名稱來代指子組件;
  2. 父組件引入 ViewChild 模塊;
  3. 父組件經過@ViewChild 獲取子組件的所有內容;

子組件經過Output給父組件傳值

一、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組件的數據');
  }
}
複製代碼

五、網頁運行效果以下:

六、小結

子組件給父組件傳值,即父組件接收子組件的屬性,大體分爲如下幾步:

  1. 子組件引入 Output、EventEmitter 模塊;
  2. 子組件將要傳輸的數據封裝在 outter 中;
  3. 父組件頁面嵌套子組件頁面,子組件聲明時須要將 outter 指向父組件中的某個方法,注意接收數據;

父子組件相互通訊

子組件 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(40Math.max(8, +this.size + delta));
    this.sizeChange.emit(this.size);
  }
}
複製代碼

sizer.component.html:

<h2>子組件</h2>
<div>
  <button (click)="dec()" title="smaller">-</button>&nbsp;&nbsp;
  <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異步數據流編程

介紹

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種方法

目前常見的異步編程的幾種方法:

  1. 回調函數
  2. 事件監聽/發佈訂閱
  3. Promise
  4. Rxjs

本次測試須要新建一個 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 本意是承諾,在程序中的意思就是承諾我過一段時間後會給你一個結果。 何時會用到過一段時間?答案是異步操做,異步是指可能比較長時間纔有結果的才作,例如網絡請求、讀取本地文件等。

它的思想是,每個異步任務返回一個 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

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);
  }
複製代碼

數據交互(Get,Post,jsonp)

Angular5.x 之後 Get、Post 和 jsonp 經過 HttpClientModule 模塊來和服務器進行數據交互。

Get獲取數據

一、 在 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;
    });
  }
}
複製代碼

四、網頁運行效果以下:

Post獲取數據

在 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 = { headersnew 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 = { headersnew 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 項目,點擊頁面上的按鈕,查看效果。

jsonp獲取數據

同 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獲取數據

一、安裝 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);
    })
  }
複製代碼

五、頁面測試

相關文章
相關標籤/搜索