首页 文章

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

提问于
浏览
23

也许我为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 回答

  • 8

    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

    在我看来,对于这种情况,我不明白为什么一个简单的Service / Observable是不够的,但这不关我的事 .

    进一步阅读:Angular 2 - Behavior Subject vs Observable?

  • 2

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

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

  • 2

    Managing login state

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

    Observable Syntax

    要回答关于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
    }
    

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

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

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

  • 2

    我想解释如何使用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的值,你必须在'create'函数中执行此操作 . 如果在这个'create'函数中声明一个函数,这将是可能的 .

相关问题