<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                上個小節的問題關鍵在于:雖然我們在組件中使用了路由獲取路由參數id的值,并使用該id獲取了相應的數據,但這個過程僅僅限制在了組件初始化的過程中。而初始化完成后路由的值雖然發生了變化,但組件全然不知。那么如果在路由的值發生變化的時候,路由來通知一下組件,組件收到通知后再重新拉取數據就可以完全規避些問題。這種變化時發出通知的方式,我們稱其為**觀察者模式**。也就是說:如果想讓路由在變化時發通知給組件,那么組件觀察著的路由就可以了,這樣一來如果路由發生了變化,組件中對此路由的觀察者就會得知。 # 觀察者模式 **觀察者模式:** A聲明自己是可以被觀察的,B將自己列為A的觀察對象,此時B便成為了A的觀察者。這類似于微信中的朋友圈,當朋友圈的好友有了新的動態時,我們第一時間能獲取到取于以下因素。 * 張三允許其它人添加為朋友。 * 我們向張三發起添加好友申請且被通過了。 * 張三發朋友圈的時候選擇的可見范圍中包括了我們。 * 我們未屏蔽張三的朋友圈。 在計算機的世界里,也是這樣: * 路由允許其它人成為它的觀察者,這是由`路由`來決定了,在`angular`中路由便有此屬性。 * 教師編輯組件需要發起好友申請來表明想觀察路由的想法,在`angular`中的路由的好友規則是:加我為朋友時不需要驗證;這個添加的過程我們稱為`subscribe 訂閱`。 * 路由發生變化時,會向所有的觀察者們發送消息,當然包含教師編輯組件,這個過程我們稱為`notice 通知`。 * 教師編輯組件接收此消息。 編寫代碼: * `route.params`是允許被觀察的。 * 統一規定通過`subscribe()`來發起好友申請) * 有新的動態后將新的動態傳給`function(data) { ... }` ``` this.route.params.subscribe(function(data) { }); ``` 改寫為箭頭函數并加入測試信息: ``` this.route.params.subscribe(data => { console.log(data); }); ``` 最后,我們將上面的代碼添加到ngOnInit()方法中,使得該方法在組件生成自動執行: ``` ngOnInit(): void { this.route.params.subscribe(data => { console.log(data); }); this.httpClient.get(this.getUrl()) .subscribe((data) => { this.teacher = data; }, () => { console.log(`請求 ${this.getUrl()} 時發生錯誤`); }); } ``` ## 測試 ![](https://img.kancloud.cn/61/c9/61c96a138413f40c202f693d56b66d52_694x439.gif) 通過測試發現,當路由發生變更時,執行了方法`console.log(data)`。這足以說明當路由發生變更時,我們得到了通知。有了這個基礎,下面對代碼進行重構。 ## 重構代碼 由于該組件對應的URL是會產生變化的,所以`getUrl()`方法并不適用`每次運算的結果均相同`的`數據緩存`理論,此時應該對`getUrl()`進行改寫。 由于在數據加載及數據更新時,都需要使用當前編輯教師的ID信息,當同一個類中兩個方法中使用共同的變量(方法)時,我們將其共同使用的變量(方法)進行剝離。 按照一事一議,減少嵌套的原則,我們將加載數據的方法由`ngOnInit`中抽離。 最終TeacherEdit組件代碼如下: ``` import {Component, OnInit} from '@angular/core'; import {ActivatedRoute, Router} from '@angular/router'; import {HttpClient} from '@angular/common/http'; import {AppComponent} from './app.component'; @Component({ templateUrl: './teacher-edit.component.html' }) export class TeacherEditComponent implements OnInit { public teacher: any = {}; private id: number; constructor(private route: ActivatedRoute, private httpClient: HttpClient, private appComponent: AppComponent, private router: Router) { } /** * 獲取與后臺對接的URL */ getUrl(): string { return 'http://localhost:8080/Teacher/' + this.id; } /** * 當路由參數發生變化時,加載教師數據。 */ load(): void { console.log('加載教師數據'); this.httpClient.get(this.getUrl()) .subscribe((data) => { this.teacher = data; }, () => { console.log(`請求 ${this.getUrl()} 時發生錯誤`); }); } ngOnInit(): void { this.route.params.subscribe(data => { console.log('路由參數發生變化,接收通知'); this.id = data.id; this.load(); }); } /** * 提交表單 */ onSubmit(): void { this.httpClient.put(this.getUrl(), this.teacher) .subscribe(() => { console.log('更新成功'); this.appComponent.ngOnInit(); this.router.navigate(['/']); }, () => { console.error(`更新數據時發生錯誤,url:${this.getUrl()}`); }); } } ``` ## 測試 ![](https://img.kancloud.cn/4d/22/4d224d58243d79294416491867708e51_692x291.gif) ## route.snapshot 如果組件生成后不再復用,即每次組件都是重新構建出來的。我們是可以簡單地使用`route.snapshot`來獲取路由參數的。但組件被復用后這招就不靈了,這是因為本身`snapshot`即是`快照`的意思,如果你使用過一些虛擬機產品對這個詞匯肯定不會感覺陌生。`快照`是對某一事件在某個特定的點留下的照片,其保存的是某個實點的信息,該信息一旦生成便不會發生變更。所以即使是后續的路由值變更了,也不會對歷史的`快照`產生影響。而如果我們通過`snapshot`來獲取信息的話,則永遠獲取的是歷史的時點值。如果在組件的生命周期(從其產生到銷毀的整個過程)中路由均未發生變化的話,調用`snapshot`可以認為就是在調用當前路由,這也是為什么在前面我們這么使用沒有發生錯誤的原因。 # 參考文檔 | 名稱 | 鏈接 | 預計學習時長(分) | | --- | --- | --- | | Angular 中的觀察者 | [https://www.angular.cn/guide/observables-in-angular#observables-in-angular](https://www.angular.cn/guide/observables-in-angular#observables-in-angular) | - | | 可觀察對象 | [https://www.angular.cn/guide/observables](https://www.angular.cn/guide/observables) | - | | 源碼地址 | [https://github.com/mengyunzhi/spring-boot-and-angular-guild/releases/tag/step2.4.7](https://github.com/mengyunzhi/spring-boot-and-angular-guild/releases/tag/step2.4.7) | - |
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看