2016-10-22 111 views
1

我使用Angular-CLI 1.0.0-beta.18(昨天更新)創建了一個項目。我試圖從組件中檢測服務中的更改。/ 訂閱Observable永不觸發

我試圖從this answer實施解決方案,this Plunkr

  • 我在服務
  • 我訂閱它從組件
  • 訂閱的更新永遠不會觸發創建一個可觀察和this cookbook,沒有骰子。

    這裏的服務:

    import { Injectable } from '@angular/core'; 
    import { ReplaySubject } from 'rxjs/ReplaySubject'; 
    import { Article } from './article'; 
    
    @Injectable() 
    export class ArticleService { 
    
        // Placeholder for article's 
        articles: Article[] = [ 
         { _id: 1, title: "Article 1", text: "Text for article 1", created: new Date() }, 
         { _id: 2, title: "Article 2", text: "Text for article 2", created: new Date() } 
        ]; 
    
        // Observable openArticle source 
        private _openArticleSource = new ReplaySubject<Article>(1); 
        // Observable openArticle stream 
        openArticle$ = this._openArticleSource.asObservable(); 
    
        // Simulate GET /articles/:_id 
        getArticleById(_id: number): Article { 
         let article = this.articles 
          .filter(article => article._id === _id) 
          .pop(); 
    
         console.log("Pushing article to observable : ", article) // This gets logged, along with the article 
         this._openArticleSource.next(article); // Should trigger the subscription, but doesn't 
    
         return article; 
        } 
    } 
    

    這裏的聆聽組件:

    import { Component } from '@angular/core'; 
    import { Subscription } from 'rxjs/Subscription'; 
    import { ArticleService } from '../article.service'; 
    
    @Component({ 
        selector: 'column-open-article', 
        templateUrl: './column-open-article.component.html', 
        providers: [ArticleService] 
    }) 
    
    
    export class ColumnOpenArticleComponent { 
    
        openArticle; 
        subscription: Subscription; 
    
        constructor(private articleService: ArticleService) { 
        this.subscription = articleService 
           .openArticle$ 
           .subscribe(article => { 
           console.log("Subscription triggered", article); // Never gets logged 
           this.openArticle = article; // Never gets updated 
           }) 
        } 
    
    
        ngOnDestroy() { 
        // prevent memory leak when component is destroyed 
        console.log("Unsubscribing") 
        this.subscription.unsubscribe(); 
        } 
    } 
    

    然後,我從另一個調用組件getArticleById(1),我可以在控制檯中看到"Pushing article to observable",所以observable已更新,但不會觸發訂閱。

    如果我將訂閱直接放在服務中,它會毫無問題地觸發,我可以在控制檯中看到"Subscription triggered"

    但是,如果我在組件中放置相同的代碼,它不起作用。

    任何想法?

回答

1

看起來您有多個ArticleService的實例。

不要在每個組件上提供ArticleService,因爲這樣每個組件實例都會得到一個新的ArticleService實例。

要麼提供它的公共父組件上,使得兩者得到從父相同的實例注入

提供它在@NgModule{ providers: [ArticleService]},那麼它將在應用根範圍andevery組件提供和注入ArticleService的服務將獲得相同的實例注入。

+0

哦,這就是它的工作原理!我認爲服務是單身人士,就像在Angular 1中一樣。實際上,他們必須在模塊級別導入一次,然後不在每個組件中導入。疑難雜症。它現在有效,非常感謝! –

+0

他們是每個提供者的單身人士。如果你有多個提供者,你會得到不止一個實例。 '@NgModule()'的提供者:[]'都被提升到根作用域,因此多個這樣的提供者仍然導致單個實例,但是對於組件或指令的提供者,每個組件或指令都會得到不同的實例。延遲加載的模塊獲取它們自己的根作用域。 –