Typescript Angular - Observable:如何改变它的价值?

时间:2017-02-28 15:19:30

标签: angular typescript observable

也许我错过了什么。我无法找到Observable及其语法的简单教程。我正在使用Angular,我需要从服务中调用一个函数(在一个组件中定义)。我读了这个solution。但是我无法弄清楚如何更改服务中创建的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?? 
    }

}

4 个答案:

答案 0 :(得分:9)

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 :(得分:4)

我想解释如何使用Observable以防你想要更新值,但我不会使用你的例子。我将只展示用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的值,你必须在&#39;创建&#39;功能。如果你在这个&#39;创建&#39;中声明一个函数,这将是可能的。功能

答案 2 :(得分:2)

我建议你改变你的病情成为一名受试者。主体既是观察者又是观察者。然后,您将能够发出一个值。

请参阅https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/subjects.md

答案 3 :(得分:2)

管理登录状态

对于此实现,您只需要一个服务。在其中,您将发出后端请求以查看用户是否有会话,然后您可以将其保存在服务中的类变量中。然后,返回该变量(如果已设置),或直接返回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);
      });

  }
}

然后在Component中,像往常一样订阅Observable并按需处理它。

使用Observable.share()Observable.replay()

还有其他方法可以实现这一目标

可观察的语法

要回答关于Angular2中Rx Observable的语法的部分问题(如果有人谷歌的话),通用形式是:

在服务中:

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
}

当收到“next”值时,将调用第一个函数。在REST调用的情况下(最常见的情况),这包含整个结果。

第二个函数是一个错误处理程序(在服务中调用Observable.trow()的情况下)。

当结果集为has时调用last,并且不带参数。您可以在此处调用doSomething()函数。