成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

【CuteJavaScript】Angular6入門項目(4.改造組件和添加HTTP服務(wù))

BDEEFE / 866人閱讀

摘要:然后我們在父組件上添加事件監(jiān)聽,并傳入本地的在對應(yīng)的中添加方法再來,我們在子組件上多導(dǎo)入和,并添加修飾器和調(diào)用這樣就實現(xiàn)了我們父子組件之間的事件傳遞啦,現(xiàn)在我們的頁面還是正常運行,并且刪除一條數(shù)據(jù)后,頁面數(shù)據(jù)會更新。

本文目錄

一、項目起步

二、編寫路由組件

三、編寫頁面組件

1.編寫單一組件

2.模擬數(shù)據(jù)

3.編寫主從組件

四、編寫服務(wù)

1.為什么需要服務(wù)

2.編寫服務(wù)

五、引入RxJS

1.關(guān)于RxJS

2.引入RxJS

3.改造數(shù)據(jù)獲取方式

六、改造組件

1.添加歷史記錄組件

2.添加和刪除歷史記錄

七、HTTP改造

1.引入HTTP

2.通過HTTP請求數(shù)據(jù)

3.通過HTTP修改數(shù)據(jù)

4.通過HTTP增加數(shù)據(jù)

5.通過HTTP刪除數(shù)據(jù)

6.通過HTTP查找數(shù)據(jù)

本項目源碼放在github

六、改造組件

從這里開始,我們要使用RxJS來改造組件和添加新功能了,讓整個項目更加完善。

1.添加歷史記錄組件

創(chuàng)建HistoryComponent組件

ng g component hostory

然后在app.component.html文件夾中添加組件:


2.添加增刪改查功能

這里我們要開始做書本的增刪改查功能,需要先創(chuàng)建一個HistoryService服務(wù),方便我們實現(xiàn)這幾個功能:

創(chuàng)建HistoryService服務(wù)

ng g service history

然后在生成的ts文件中,增加addclear方法,add方法用來添加歷史記錄到history數(shù)組中,clear方法則是清空history數(shù)組:

// history.service.ts
export class HistoryService {
    history: string[] = [];
    add(history: string){
        this.history.push(history);
    }
    clear(){
        this.history = [];
    }
}

使用HistoryService服務(wù)

在將這個服務(wù),注入到BooksService中,并改造getBooks方法:

// books.service.ts
import { HistoryService } from "./history.service";
constructor(
    private historyservice: HistoryService
) { }
getBooks(): void{
    this.historyservice.add("請求書本數(shù)據(jù)")
    this.booksservice.getBookList()
        .subscribe(books => this.books = books);
}

也可以用相同方法,在IndexComponent中添加訪問首頁書本列表的記錄。

// index.component.ts
import { HistoryService } from "../history.service";
constructor(
    private booksservice: BooksService,
    private historyservice: HistoryService
) { }
getBooks(): void{
    this.historyservice.add("訪問首頁書本列表");
    this.booksservice.getBookList()
        .subscribe(books => this.books = books);
}

接下來,將我們的HistoryService注入到HistoryComponent中,然后才能將歷史數(shù)據(jù)顯示到頁面上:

// history.component.ts
import { HistoryService } from "../history.service";
export class HistoryComponent implements OnInit {
    constructor(private historyservice: HistoryService) { }
    ngOnInit() {}
}

操作歷史:

{{item}}

代碼解釋
*ngIf="historyservice.history.length",是為了防止還沒有拿到歷史數(shù)據(jù),導(dǎo)致后面的報錯。
(click)="historyservice.clear()", 綁定我們服務(wù)中的clear事件,實現(xiàn)清除緩存。
*ngFor="let item of historyservice.history",將我們的歷史數(shù)據(jù)渲染到頁面上。

到了這一步,就能看到歷史數(shù)據(jù)了,每次也換到首頁,都會增加一條。

接下來,我們要在書本詳情頁也加上歷史記錄的統(tǒng)計,導(dǎo)入文件,注入服務(wù),然后改造getBooks方法,實現(xiàn)歷史記錄的統(tǒng)計:

// detail.component.ts
import { HistoryService } from "../history.service";

export class DetailComponent implements OnInit {
    constructor(
        private route: ActivatedRoute,
        private location: Location,
        private booksservice: BooksService,
        private historyservice: HistoryService
    ) { }
    //...
    getBooks(id: number): void {
        this.books = this.booksservice.getBook(id);
        this.historyservice.add(`查看書本${this.books.title},id為${this.books.id}`);
        console.log(this.books)
    }
}

這時候就可以在歷史記錄中,看到這些操作的記錄了,并且清除按鈕也正常使用。

七、HTTP改造

原本我只想寫到上一章,但是想到,我們實際開發(fā)中,哪有什么本地數(shù)據(jù),基本上數(shù)據(jù)都是要從服務(wù)端去請求,所以這邊也有必要引入這一張,模擬實際的HTTP請求。

1.引入HTTP

在這一章,我們使用Angular提供的 HttpClient 來添加一些數(shù)據(jù)持久化特性。
然后實現(xiàn)對書本數(shù)據(jù)進行獲取,增加,修改,刪除和查找功能。

HttpClient是Angular通過 HTTP 與遠程服務(wù)器通訊的機制。

這里我們?yōu)榱俗?b>HttpClient在整個應(yīng)用全局使用,所以將HttpClient導(dǎo)入到根模塊app.module.ts中,然后把它加入 @NgModule.imports 數(shù)組:

import { HttpClientModule } from "@angular/common/http";
@NgModule({
    //...
    imports: [
        BrowserModule,
        AppRoutingModule,
        HttpClientModule
    ],
    //...
})

這邊我們使用 內(nèi)存 Web API(In-memory Web API) 模擬出的遠程數(shù)據(jù)服務(wù)器通訊。
注意: 這個內(nèi)存 Web API 模塊與 Angular 中的 HTTP 模塊無關(guān)。

通過下面命令來安裝:

npm install angular-in-memory-web-api --save

然后在app.module.ts中導(dǎo)入 HttpClientInMemoryWebApiModuleInMemoryDataService 類(后面創(chuàng)建):

// app.module.ts
import { HttpClientInMemoryWebApiModule } from "angular-in-memory-web-api";
import { InMemoryDataService }  from "./in-memory-data.service";
@NgModule({
    // ...
    imports: [
        // ...
        HttpClientInMemoryWebApiModule.forRoot(
        InMemoryDataService, {dataEncapsulation:false}
        )
    ],
    // ...
})
export class AppModule { }

知識點:
forRoot() 配置方法接受一個 InMemoryDataService 類(初期的內(nèi)存數(shù)據(jù)庫)作為參數(shù)。

然后我們要創(chuàng)建InMemoryDataService類:

ng g service InMemoryData

并將生成的in-memory-data.service.ts修改為:

// in-memory-data.service.ts
import { Injectable } from "@angular/core";
import { InMemoryDbService } from "angular-in-memory-web-api";
import { Books } from "./books";
@Injectable({
  providedIn: "root"
})
export class InMemoryDataService implements InMemoryDbService {
  createDb(){
    const books = [
      {
          id: 1, 
          url: "https://img3.doubanio.com/view/subject/m/public/s29988481.jpg",
          title: "像火焰像灰燼",
          author: "程姬",
      },
      // 省略其他9條數(shù)據(jù)
    ];
    return {books};
  }
  constructor() { }
}

這里先總結(jié)InMemoryDbService所提供的RESTful API,后面都要用到:
例如如果urlapi/books,那么

查詢所有成員:以GET方法訪問api/books

查詢某個成員:以GET方法訪問api/books/id,比如id1,那么訪問api/books/1

更新某個成員:以PUT方法訪問api/books/id

刪除某個成員:以DELETE方法訪問api/books/id

增加一個成員:以POST方法訪問api/books

2.通過HTTP請求數(shù)據(jù)

現(xiàn)在要為接下來的網(wǎng)絡(luò)請求做一些準(zhǔn)備,先在books.service.ts中引入HTTP符號,然后注入HttpClient并改造:

// books.service.ts
import { HttpClient, HttpHeaders} from "@angular/common/http";
// ...
export class BooksService {
    constructor(
        private historyservice: HistoryService,
        private http: HttpClient
    ) { }
    private log(histories: string){
        this.historyservice.add(`正在執(zhí)行:${histories}`)
    }
    private booksUrl = "api/books"; // 提供一個API供調(diào)用
    // ...
}

這里我們還新增一個私有方法log和一個私有變量booksUrl。

接下來我們要開始發(fā)起http請求數(shù)據(jù),開始改造getBookList方法:

// books.service.ts
// ...
getBookList(): Observable {
    this.historyservice.add("請求書本數(shù)據(jù)")
    return this.http.get(this.booksUrl);
}
// ...

這里我們使用 http.get 替換了 of,其它沒修改,但是應(yīng)用仍然在正常工作,這是因為這兩個函數(shù)都返回了 Observable。

實際開發(fā)中,我們還需要考慮到請求的錯誤處理,要捕獲錯誤,我們就要使用 RxJS 的 catchError() 操作符來建立對 Observable 結(jié)果的處理管道(pipe)。

我們引入catchError 并改造原本getBookList方法:

// books.service.ts
getBookList(): Observable {
    this.historyservice.add("請求書本數(shù)據(jù)")
    return this.http.get(this.booksUrl).pipe(
        catchError(this.handleError("getHeroes", []))
    );
}
private handleError (operation = "operation", result?: T) {
    return (error: any): Observable => {
        this.log(`${operation} 失敗: ${error.message}`); // 發(fā)出錯誤通知
        return of(result as T); // 返回空結(jié)果避免程序出錯
    };
}

知識點
.pipe() 方法用來擴展 Observable 的結(jié)果。
catchError() 操作符會攔截失敗的 Observable。并把錯誤對象傳給錯誤處理器,錯誤處理器會處理這個錯誤。
handleError() 錯誤處理函數(shù)做了兩件事,發(fā)出錯誤通知和返回空結(jié)果避免程序出錯。

這里還需要使用tap操作符改造getBookList方法,來窺探Observable數(shù)據(jù)流,它會查看Observable的值,然后我們使用log方法,記錄一條歷史記錄。
tap 回調(diào)不會改變這些值本身。

// books.service.ts
getBookList(): Observable {
    return this.http.get(this.booksUrl)
        .pipe(
            tap( _ => this.log("請求書本數(shù)據(jù)")),
            catchError(this.handleError("getHeroes", []))
        );
}
3.通過HTTP修改數(shù)據(jù)

這里我們需要在原來DetailComponent上面,添加一個輸入框、保存按鈕和返回按鈕,就像這樣:



修改信息:

這邊切記一點,一定要在app.module.ts中引入 FormsModule模塊,并在@NgModuleimports中引入,不然要報錯了。

// app.module.ts
// ...
import { FormsModule } from "@angular/forms"; 
@NgModule({
    // ...
    imports: [
        // ...
        FormsModule
    ],
    // ...
})

input框綁定書本的標(biāo)題books.title,而保存按鈕綁定一個save()方法,這里還要實現(xiàn)這個方法:

// detail.component.ts
save(): void {
    this.historyservice.updateBooks(this.books)
        .subscribe(() => this.goBack());
}
goBack(): void {
    this.location.back();
}

這里通過調(diào)用BooksServiceupdateBooks方法,將當(dāng)前修改后的書本信息修改到源數(shù)據(jù)中,這里我們需要去books.service.ts中添加updateBooks方法:

// books.service.ts
// ...
updateBooks(books: Books): Observable{
    return this.http.put(this.booksUrl, books, httpOptions).pipe(
        tap(_ => this.log(`修改書本的id是${books.id}`)),
        catchError(this.handleError(`getBooks請求是id為${books.id}`))
    )
}
// ...

知識點
HttpClient.put() 方法接受三個參數(shù):URL 地址、要修改的數(shù)據(jù)其他選項
httpOptions 常量需要定義在@Injectable修飾器之前。

現(xiàn)在,我們點擊首頁,選擇一本書進入詳情,修改標(biāo)題然后保存,會發(fā)現(xiàn),首頁上這本書的名稱也會跟著改變呢。這算是好了。

4.通過HTTP增加數(shù)據(jù)

我們可以新增一個頁面,并添加上路由和按鈕:

ng g component add

添加路由:

// app-routing.module.ts
// ...
import { AddComponent } from "./add/add.component";

const routes: Routes = [
  { path: "", redirectTo:"/index", pathMatch:"full" },
  { path: "index", component: IndexComponent},
  { path: "detail/:id", component: DetailComponent},
  { path: "add", component: AddComponent},
]

添加路由入口:



添加書本

編輯添加書本的頁面:


添加書本:

初始化添加書本的數(shù)據(jù):

// add.component.ts
// ...
import { Books } from "../books";
import { BooksService } from "../books.service";
import { HistoryService } from "../history.service";
import { Location } from "@angular/common";
export class AddComponent implements OnInit {
    books: Books = {
        id: 0,
        url: "",
        title: "",
        author: ""
    }
    constructor(
        private location: Location,
        private booksservice: BooksService,
        private historyservice: HistoryService
    ) { }
    ngOnInit() {}
    add(books: Books): void{
        books.title = books.title.trim();
        books.author = books.author.trim();
        this.booksservice.addBooks(books)
        .subscribe( book => {
            this.historyservice.add(`新增書本${books.title},id為${books.id}`);
            this.location.back();
        });
    }
}

然后在books.service.ts中添加addBooks方法,來添加一本書本的數(shù)據(jù):

// books.service.ts
addBooks(books: Books): Observable{
    return this.http.post(this.booksUrl, books, httpOptions).pipe(
        tap((newBook: Books) => this.log(`新增書本的id為${newBook.id}`)),
        catchError(this.handleError("添加新書"))
    );
}

現(xiàn)在就可以正常添加書本啦。

5.通過HTTP刪除數(shù)據(jù)

這里我們先為每個書本后面添加一個刪除按鈕,并綁定刪除事件delete



X
// books.component.ts
import { BooksService } from "../books.service";
export class BooksComponent implements OnInit {
  @Input() list: Books;
  constructor(
    private booksservice: BooksService
  ) { }
  // ...
  delete(books: Books): void {
    this.booksservice.deleteBooks(books)
      .subscribe();
  }
}

然后還要再books.service.ts中添加deleteBooks方法來刪除:

// books.service.ts
deleteBooks(books: Books): Observable{
    const id = books.id;
    const url = `${this.booksUrl}/${id}`;
    return this.http.delete(url, httpOptions).pipe(
        tap(_ => this.log(`刪除書本${books.title},id為${books.id}`)),
        catchError(this.handleError("刪除書本"))
    );
}

這里需要在刪除書本結(jié)束后,通知IndexComponent將數(shù)據(jù)列表中的這條數(shù)據(jù)刪除,這里還需要再了解一下Angular 父子組件數(shù)據(jù)通信。
然后我們在父組件IndexComponent上添加change事件監(jiān)聽,并傳入本地的funChange


在對應(yīng)的index.component.ts中添加funChange方法:

// index.component.ts
funChange(books, $event){
    this.books = this.books.filter(h => h.id !== books.id);
}

再來,我們在子組件BooksComponent上多導(dǎo)入OutputEventEmitter,并添加@Output()修飾器和調(diào)用emit

import { Component, OnInit, Input, Output, EventEmitter } from "@angular/core";
export class BooksComponent implements OnInit {
    // ... 
    @Output()
    change = new EventEmitter()
    // ... 
    delete(books: Books): void {
        this.booksservice.deleteBooks(books)
        .subscribe(()=>{
            this.change.emit(books);
        });
    }
}

這樣就實現(xiàn)了我們父子組件之間的事件傳遞啦,現(xiàn)在我們的頁面還是正常運行,并且刪除一條數(shù)據(jù)后,頁面數(shù)據(jù)會更新。

6.通過HTTP查找數(shù)據(jù)

還是在books.service.ts,我們添加一個方法getBooks,來實現(xiàn)通過ID來查找指定書本,因為我們是通過ID查找,所以返回的是單個數(shù)據(jù),這里就是Observable類型:

// books.service.ts
getBooks(id: number): Observable{
    const url = `${this.booksUrl}/${id}`;
    return this.http.get(url).pipe(
        tap( _ => this.log(`請求書本的id為${id}`)),
        catchError(this.handleError(`getBooks請求是id為${id}`))
    )
}

注意,這里 getBooks 會返回 Observable,是一個可觀察的單個對象,而不是一個可觀察的對象數(shù)組。

八、結(jié)語

這個項目其實很簡單,但是我還是一步一步的寫下來,一方面讓自己更熟悉Angular,另一方面也是希望能幫助到更多朋友哈~
最終效果:

本部分內(nèi)容到這結(jié)束

Author 王平安
E-mail [email protected]
博 客 www.pingan8787.com
微 信 pingan8787
每日文章推薦 https://github.com/pingan8787...
JS小冊 js.pingan8787.com
微信公眾號 前端自習(xí)課

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/102024.html

相關(guān)文章

  • CuteJavaScriptAngular6入門項目(2.構(gòu)建項目頁面組件

    摘要:編寫單一組件我們首先寫一個書本信息的組件,代碼如下單個課本像火焰像灰燼程姬知識點是一個的復(fù)寫器指令,就像中的和中的。寫到這里,看看我們項目,還是一樣正常在運行,只是現(xiàn)在項目中組件分工更加明確了。 本文目錄 一、項目起步 二、編寫路由組件 三、編寫頁面組件 1.編寫單一組件 2.模擬數(shù)據(jù) 3.編寫主從組件 四、編寫服務(wù) 1.為什么需要服務(wù) 2.編寫服務(wù) 五、...

    Lemon_95 評論0 收藏0
  • CuteJavaScriptAngular6入門項目(3.編寫服務(wù)引入RxJS)

    摘要:發(fā)布通過回調(diào)方法向發(fā)布事件。觀察者一個回調(diào)函數(shù)的集合,它知道如何去監(jiān)聽由提供的值。 本文目錄 一、項目起步 二、編寫路由組件 三、編寫頁面組件 1.編寫單一組件 2.模擬數(shù)據(jù) 3.編寫主從組件 四、編寫服務(wù) 1.為什么需要服務(wù) 2.編寫服務(wù) 五、引入RxJS 1.關(guān)于RxJS 2.引入RxJS 3.改造數(shù)據(jù)獲取方式 六、改造組件 1.添...

    RebeccaZhong 評論0 收藏0
  • CuteJavaScriptAngular6入門項目(1.構(gòu)建項目創(chuàng)建路由)

    摘要:啟動服務(wù),并打開新窗口可簡寫創(chuàng)建新組件可簡寫創(chuàng)建新服務(wù)創(chuàng)建路由模塊其他另外還有很多的命令提供,詳細(xì)可以查閱官方文檔命令。引入路由模塊導(dǎo)出路由模塊的指令這里需要添加一個數(shù)組,并傳入,導(dǎo)出讓路由器的相關(guān)指令可以在中的組件中使用。 本文目錄 一、項目起步 二、編寫路由組件 三、編寫頁面組件 1.編寫單一組件 2.模擬數(shù)據(jù) 3.編寫主從組件 四、編寫服務(wù) 1.為什么需要服務(wù) 2....

    bergwhite 評論0 收藏0
  • CuteJavaScript】GraphQL真香入門教程

    摘要:最終代碼省略其他輸入類型用標(biāo)識查詢類型需要至少定義一個不要會不顯示查詢這里需要轉(zhuǎn)成數(shù)組因為前面定義了返回值是類型相當(dāng)于數(shù)據(jù)庫的添加操作相當(dāng)于數(shù)據(jù)庫的更新操作省略其他現(xiàn)在我們可以啟動服務(wù)器,在上測試下效果了。 showImg(https://segmentfault.com/img/remote/1460000019142304?w=893&h=438); 看完復(fù)聯(lián)四,我整理了這份 Gr...

    bingo 評論0 收藏0
  • angular6入門之安裝angular-cli

    摘要:由于之前安裝的是的版本,需要卸載了,安裝最新的版本。清除緩存,確保卸載干凈具體參考安裝最新版本安裝成功后提示意思是版的需要版本最低,我之前的是的版本。先安裝,去下載安裝。在命令行輸入檢查是否安裝成功。 最近聽了大漠老師分享的angular6的講解(附個鏈接大漠老師課程:http://www.ngfans.net/topic/2...),像是沙漠中發(fā)現(xiàn)了綠洲一樣,決定好好學(xué)習(xí)一番,于是準(zhǔn)...

    loonggg 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<