web-dev-qa-db-ja.com

Typescript Angular-観測可能:値を変更する方法

たぶん私は何かが欠けています。 Observableとその構文の簡単なチュートリアルが見つかりません。私は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?? 
    }

}
27
Johannes

他の答え (誰かに役立つかもしれないので保存されています)のコメントから、何かの力を利用して値を出力する時間をかけて

DOMZEが提案したように、件名を使用しますが、これはhowを示す(簡単な)例です。明らかに Subjectを直接使用する際に避けるべき落とし穴 がありますが、それはあなたにお任せします。

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?

11
msanford

値を更新する場合にObservablesを使用する方法を説明しますが、例を使用しません。 ES5で記述された数行のコードを説明とともに表示します。

var updateObservable; // declare here in order to have access to future function

var observable = rx.Observable.create(function (observer) {
  observer.next(1);
  observer.next(2);
  observer.next(3);

  // attach a function to the variable which was created in the outer scope
  // by doing this, you now have your 'updateObservable' as a function and the reference to it as well
  // You will be able to call this function when want to update the value
  updateObservable = function (newValue) {
    observer.next(newValue);
    observer.complete();
  };
});

// Suppose you want to update on click. Here actually can be whatever (event) you want
vm.click = function () {
  // you can call this function because you have a reference to it
  // and pass a new value to your observable
  updateObservable(4);
};

// your subscription to changes
observable.subscribe(function(data) {
  // after 'click' event will be performed, subscribe will be fired
  // and the '4' value will be printed
  console.log(data);
});

ここでの主なアイデアは、Observableの値を更新する場合は、「作成」関数内でこれを行う必要があるということです。これは、この「作成」関数内で関数を宣言すると可能になります。

6
EA0906

件名に条件を変更することをお勧めします。サブジェクトは、オブザーバーとオブザーバブルの両方です。その後、値を発行できるようになります。

https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/subjects.md を参照してください

3
DOMZE

ログイン状態の管理

この実装では、必要なサービスは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をサブスクライブし、オンデマンドでそれを実行します。

Observable.share() および Observable.replay() でこれを達成する他の方法があります

観察可能な構文

Angular2のRx Observableの構文に関する質問の一部に答えるために(誰かがGoogleにすべきです)、一般的な形式は次のとおりです。

サービス内:

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呼び出しの場合(最も一般的なケース)、これには結果全体が含まれます。

2番目の関数はエラーハンドラです(サービスでObservable.trow()が呼び出された場合)。

最後は、結果セットがあったときに呼び出され、パラメータを取りません。ここでdoSomething()関数を呼び出すことができます。

2
msanford