2016-10-22 110 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()'的提供者:[]'都被提升到根作用域,因此多个这样的提供者仍然导致单个实例,但是对于组件或指令的提供者,每个组件或指令都会得到不同的实例。延迟加载的模块获取它们自己的根作用域。 –