2017-05-04 17 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)); 

一切工作正常。