2017-08-21 72 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}}或訂閱。