2017-05-04 56 views
2

我只是通過閱讀v.4.0的教程來學習Angular。我剛剛參加了該教程的Section 6(路由),並且我理解了subscribe方法。我會很樂意爲你解釋一下。有人可以解釋Angular訂閱方法

據我所知,ngOnInit()被調用一次,這就是爲什麼我們在這裏使用subscribe()。但是,什麼事件使subscribe()被觸發?只有當再次請求包含特定HeroDetailComponent的頁面時纔會觸發它。爲了我的理解,它必須附加到ActivatedRoute.params上的某種'onChange'事件,並在用戶請求同一頁面時觸發(包含HeroDetailComponent)。

一旦ActivatedRoute.params改變會發生什麼呢?我的意思是 - 如果ngOnInit()只執行一次,this.hero如何分配一個新值。我很好奇它是如何知道執行this.heroService.getHero(+params['id'])並將返回值分配給this.hero?從教程here

// mock-heroes.ts 
export const HEROES: Hero[] = [ 
    { id: 11, name: 'Mr. Nice' }, 
    { id: 12, name: 'Narco' }, 
    { id: 13, name: 'Bombasto' }, 
    { id: 14, name: 'Celeritas' }, 
    { id: 15, name: 'Magneta' }, 
    { id: 16, name: 'RubberMan' }, 
    { id: 17, name: 'Dynama' }, 
    { id: 18, name: 'Dr IQ' }, 
    { id: 19, name: 'Magma' }, 
    { id: 20, name: 'Tornado' } 
]; 

// hero.service.ts 
@Injectable() 
export class HeroService { 
    getHeroes(): Promise<Hero[]> { 
     return Promise.resolve(HEROES); 
    } 
    getHero(id: number): Promise<Hero> { 
     return this.getHeroes() 
     .then(heroes => heroes.find(hero => hero.id === id)); 
    } 

// hero-detail.component.ts 
@Component({...}) 
export class HeroDetailComponent implements OnInit{ 
    constructor(
     private heroService: HeroService, 
     private route: ActivatedRoute, 
     private location: Location 
    ) {} 

    ngOnInit(): void { 
     this.route.params 
     .switchMap((params: Params) => this.heroService.getHero(+params['id'])) 
     .subscribe(hero => this.hero = hero); 
    } 

編輯

完整的源代碼: 我剛剛發現了一個great article如果有人有問題理解這些概念,這可能是有用的。

+1

請參閱:http://xgrommx.github.io/rx-book/content/observable/observable_instance_methods/subscribe.html和https://xgrommx.github.io/rx-book/content/getting_started_with_rxjs/creating_and_querying_observable_sequences/ creating_and_subscribing_to_simple_observable_sequences.html – wannadream

回答

1

1)subscribe()是rxjs的一部分,不是角度。爲了充分了解它是如何工作 - 去rxjs文檔:)

2)對於基本的理解,假設您有類/對象像(實Observable得多複雜,這僅僅是僞代碼):

type CallbackFunction =() => void; 

class ObservableImitation{ 

    private subscribers: CallbackFunction[] = []; 

    constructor(){}; 

    public subscribe(callback: CallbackFunction){ 
     this.subscribers.push(callback); 
    } 

    public next(value?: any){ 
     this.subscribers.forEach((callback: CallbackFunction) => callback(value)); 
    } 

} 

基本上,當你.subscribe(),你的回調被添加到數組。當其他人呼叫.next()(在Router的情況下,它在其代碼內被調用)在Observable上時,它開始在所有subscribers上循環。

爲了防止意外的內存泄漏和錯誤,當組件被銷燬(如果它完全被銷燬,例如,一些抽象的NavBarComponent始終停留在屏幕上),最好應該unsubscribe()

更重要的是typescript/js/es如何解決回調的this。但這是另一個話題的問題。所有你必須考慮在這一點上,只要你做

.subscribe(() => { 
    this.doSomething(); 
    this.doSomethingElse(); 
}); 

.subscribe(() => this.doSomething()); 

.subscribe(this.doSomething.bind(this)); 

一切工作正常。