2017-08-21 124 views
3

我试图创建一个服务来共享两个组件之间的数据。我将该服务注入到根模块中,以便通过在根模块提供程序中执行DI来在整个应用程序中访问该服务。我的代码看起来大致如此。Angular 4 Singleton Services

服务

@Injectable(){ 
    export class ForumService{ 
     forum: any; 

     setForum(object){ 
      this.forum = object; 
     } 

     getForum(){ 
      return this.forum; 
     } 
    } 

根模块

....... 
import { ForumService } from 'forumservice'; 
....... 

@NgModule({ 
    declarations: [.....], 
    imports: [.....], 
    providers: [....., ForumService], 
    bootstrap: [AppComponent] 
}) 
export class AppModule{} 

部件的一个

//A bunch of import statements 

import { ForumService } from 'forumservice'; //Without this Angular throws a compilation error 

@Component({ 
    selector: 'app-general-discussion', 
    templateUrl: './general-discussion.component.html', 
    styleUrls: ['./general-discussion.component.css'], 
    providers: [GeneralDiscussionService]  //Not injecting ForumService again 
}) 

export class GeneralDiscussionComponent implements OnInit{ 

    constructor(private forumService: ForumService){} 

    ngOnInit(){ 
    helperFunction(); 
    } 

    helperFunction(){ 
    //Get data from backend and set it to the ForumService 
    this.forumService.forum = data; 
    console.log(this.forumService.forum); //prints the data, not undefined 
    } 
} 

组件两个

//A bunch of import statements 

import { ForumService } from 'forumservice'; //Without this Angular throws a compilation error 

@Component({ 
    selector: 'app-forum', 
    templateUrl: './forum.component.html', 
    styleUrls: ['./forum.component.css'], 
    providers: [] 
}) 

export class ForumComponent implements OnInit { 
    forumData: any; 

    constructor(private forumService: ForumService){} 

    ngOnInit(){ 
     this.forumData = this.forumService.forum; // returns undefined   
    } 
} 

有一次,我从组件之间导航,组件两个我期待“这是一个字符串”。但我得到undefined。是否因为组件中的导入语句?如果我删除,我看到一个编译错误说没有找到ForumService

+1

我很确定这是一个计时问题,在设置之前读取值。尝试在构造函数中设置而不是'ngOnInit'。我的建议是使用'BehaviorSubject'来解决这种问题,而不是一个公正的领域。 –

回答

0

不是使用getter和setter,而是直接在组件中使用对象(而不是primitibe,如字符串)。

您的服务

@Injectable(){ 
export class ForumService{ 
    forum:any = {name:string}; 
} 

组件一个

export class GeneralDiscussionComponent implements OnInit{ 

    constructor(private forumService: ForumService){} 

    ngOnInit(){ 
    this.forumService.forum.name="This is a string"; 
    } 
} 

组件2

export class ForumComponent implements OnInit { 
// forumTitle: string; // do not need this anymore 
    forum:any; // use the forum.name property in your html 

    constructor(private forumService: ForumService){} 

    ngOnInit(){ 
     this.forum = this.forumService.forum; // use the   
    } 
} 

我知道ENCA psulating是可取的,并且用您当前的代码可能会遇到一些计时问题。但是,当处理服务中的共享数据时,您可以双向绑定上述变量,并且您的组件将同步。

编辑:

也是一个重要的通知,想要组件之间同步的变量需要是一个对象。而不是forumTitle:string,使它forumTitle:any = {subject:string}或类似的东西。

否则,当数据在服务中发生变化时,您需要将组件作为数据的侦听器。

+0

仍然收到'undefined'。是否因为在组件中导入ForumService? – adityav

+0

我只注意到另一件重要的事情。该变量不能是一个基元(比如字符串),它需要成为一个对象。例如。 'forumTitle:any = {subject:string};' – John

+0

尝试过一个对象。仍然不起作用。 – adityav

0

我会用BehaviorSubject在这种情况下,应该是类似的东西:

@Injectable(){ 
export class ForumService{ 
    private _forum: BehaviorSubject<any> = new BehaviorSubject<any>(null); 
    public forum: Observable<any> = this._forum.asObservable(); 

    setForum(object){ 
     this._forum.next(object); 
    } 

} 

然后只需用异步管其绑定模板:{{forumService.forum|async}}或订阅。