2017-02-28 23 views
9

也許我錯過了一些東西。我無法找到Observable及其語法的簡單教程。我正在使用Angular,我需要從服務中調用一個函數(在一個組件中定義)。我讀了solution。但我無法弄清楚如何改變服務中創建的Observable的值(也許創建不是最好的方法)。Typescript Angular - Observable:如何更改其值?

我有一個成分像的解決方案:

@Component({ 
    selector: 'my-component', 
    ... 
)} 
export class MyComponent { 
    constructor(myService:MyService) { 
    myService.condition.subscribe(value => doSomething(value)); 
} 

doSomething(value) { 
    if (value) // do stuff 
    else // other stuff 
} 

}

,這是我的服務:

import { Injectable } from '@angular/core'; 
import { Observable} from 'rxjs/Observable'; 

@Injectable() 

export class MyService { 
    private condition: Observable<boolean>; 
    constructor() { 
     this.condition= new Observable(ob => {ob.next(false); }) 
     // maybe ob.next is not the best solution to assign the value? 
    } 

    change() {// how can i change the value of condition to 'true', to call 
       // the doSomething function in the component?? 
    } 

} 
+0

我無法準確提取您想要執行的操作。你能否給你的問題多一些背景?爲什麼你(想)你想從一個服務調用一個組件功能? Observable就像是一種承諾:通常用在Component中,當某個異步操作完成時,要求Service返回一個Observable,並在Component(或另一個Service)內部採取行動。 – msanford

+0

您鏈接的其他問題與使用服務作爲兩個組件之間的中介相關。這是你想要做的嗎? – msanford

+0

'this.condition = Observable.of(false)'爲你工作嗎? – msanford

回答

4

從關於my other answer的評論(因爲它可能對某人有幫助而被保留),您似乎想要利用某些東西的強大功能隨着時間的推移

由於DOMZE提出,使用主題,但這裏是一個(微不足道)示例如何你可以做到這一點。雖然有明顯的some pitfalls to avoid in using Subject directly,但我會留給你的。

import { Component, NgModule } from '@angular/core' 
import { BrowserModule } from '@angular/platform-browser' 
import { Observable, Subject } from 'rxjs/Rx'; 

@Component({ 
    selector: 'my-app', 
    template: ` 
    <div> 
     <h2>Open the console.</h2> 
    </div> 
    `, 
}) 
export class App { 

    constructor() {} 

    let subject = new Subject(); 

    // Subscribe in Component 
    subject.subscribe(next => { 
    console.log(next); 
    }); 

    setInterval(() => { 
    // Make your auth call and export this from Service 
    subject.next(new Date()) 
    }, 1000) 
} 

@NgModule({ 
    imports: [ BrowserModule ], 
    declarations: [ App ], 
    bootstrap: [ App ] 
}) 
export class AppModule {} 

Plunker

在我的愚見,對於這種情況,我不明白爲什麼一個簡單的服務/可觀察是不夠的,但是這是我的事。

延伸閱讀:Angular 2 - Behavior Subject vs Observable?

+1

謝謝!可能對我的問題的解釋不是很好(我不是英語),所以感謝您的耐心。我嘗試了這個主題,它對我的​​目的(和BehaviorSubject)來說似乎是完美的。 – Johannes

+1

@Johannes對我來說,這也是一個有趣的問題,所以歡迎您! (你的英語非常好,我也來自另一個語言背景;)) – msanford

1

管理登錄狀態

對於此實現,您只需要一個服務。在它中,你可以讓你的後端請求查看用戶是否有會話,然後你可以將它保存在服務中的類變量中。然後,如果該變量已設置,則返回該變量,或直接返回REST調用的結果。

例如:

export class AuthenticationService { 

private loggedIn: boolean = null; 

constructor(private http: Http) { } 

getUserSession(credentials): Observable<boolean> { 

    if (this.loggedIn !== null) { 

    return Observable.of(this.loggedIn); 

    } else { 

    return this.http.get('/authenticate?' + credentials) 
     .map((session: Response) => session.json()) 
     .catch(e => { 
     // If a server-side login gate returns an HTML page... 
     return Observable.of(false); 
     }); 

    } 
} 

然後在組件,只需訂閱可觀察像往常一樣,並作用於它的點播。

沒有與Observable.share()Observable.replay()實現這一

可觀察語法

解答有關的Rx可觀察到的Angular2語法問題的一部分,其他的方法(應該有人谷歌它),在一般形式是:

在服務:

return this.http.get("/people", null) 
    .map(res.json()) 
    .catch(console.error("Error in service") 

,且在組件,通過示例的方式:

this.someService.getPeople() 
    .subscribe(
    people => this.people, 
    error => console.warn('Problem getting people: ' + error), 
    () => this.doneHandler(); 
); 

形式上:

interface Observer<T> { 
    onNext(value: T) : void 
    onError(error: Error) : void 
    onCompleted() : void 
} 

接收到「下一個」值時,第一函數被調用。在REST調用的情況下(最常見的情況),這包含整個結果。

第二個函數是錯誤處理程序(在服務中調用Observable.trow()的情況下)。

當結果集已有並且不帶參數時調用最後一個。這是您可以調用doSomething()函數的地方。

+0

謝謝,我正在嘗試這種方法。但通常,我想了解一種方法來「告訴」一個組件X,即在服務中變量值被改變;所以,在一個組件中,我想訂閱該變量。 – Johannes

+0

@Johannes我明白你的意思了,所以這就是爲什麼你在使用'Observable.next()',所以你可以使用它幾乎就像一個ES6 _ * generator_?或者保持雙向數據綁定的精神,但是從服務到組件,而不是組件到視圖。想到幾個想法不是非常習慣的ng2,但這是一個有趣的問題,所以我會自己檢查一下,如果我發現了什麼,請發表另一個答案。 – msanford