如何在Angular中从静态数据创建类似于HTTP的Observable?

169

我有一个服务,其中有这个方法:

export class TestModelService {

    public testModel: TestModel;

    constructor( @Inject(Http) public http: Http) {
    }

    public fetchModel(uuid: string = undefined): Observable<string> {
        if(!uuid) {
            //return Observable of JSON.stringify(new TestModel());
        }
        else {
            return this.http.get("http://localhost:8080/myapp/api/model/" + uuid)
                .map(res => res.text());
        }
    }
}

在组件的构造函数中,我像这样订阅:

export class MyComponent {
   testModel: TestModel;
   testModelService: TestModelService;

   constructor(@Inject(TestModelService) testModelService) {
      this.testModelService = testModelService;

      testService.fetchModel("29f4fddc-155a-4f26-9db6-5a431ecd5d44").subscribe(
          data => { this.testModel = FactModel.fromJson(JSON.parse(data)); },
          err => console.log(err)
      );
   }
}

如果一个对象来自服务器,那么这可以运行。但是我正在尝试创建一个可观察对象,使其能够与给定的subscribe()调用一起使用静态字符串(当testModelService.fetchModel()未收到uuid时会发生这种情况),以便在两种情况下都有无缝处理。

6个回答

185

或许你可以尝试使用 Observable 类的 of 方法:

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';

public fetchModel(uuid: string = undefined): Observable<string> {
  if(!uuid) {
    return Observable.of(new TestModel()).map(o => JSON.stringify(o));
  }
  else {
    return this.http.get("http://localhost:8080/myapp/api/model/" + uuid)
            .map(res => res.text());
  }
}

2
太棒了!它起作用了!我尝试了很多东西,如Observable.from()等。目前Observable的API文档不是最清晰/最用户友好的!谢谢 :) - Michail Michailidis
66
如果您正在使用版本6,您需要import { of } from 'rxjs';并使用of,而不是Observable.of - vip
3
对于 Angular v7.x.x 版本,在使用 get 方法后,结果中没有 .map() 函数,因此需要使用 .pipe(map((res:any) => res.json()))。参见这里:https://dev59.com/51wX5IYBdhLWcg3wjgCf#35220045。 - Michail Michailidis

126

截至 2018 年 7月和 RxJS 6 版本的发布,从一个值获取 Observable 的新的方法是导入 of 操作符,如下所示:

import { of } from 'rxjs';

然后从该值创建可观察对象,就像这样:

of(someValue);

请注意,您以前必须像目前已接受的答案中所示那样执行 Observable.of(someValue)。有一篇很好的文章介绍了RxJS 6的其他更改 在这里


23

自从Angular 2.0.0以来,情况似乎已经发生了变化。

import { Observable } from 'rxjs/Observable';
import { Subscriber } from 'rxjs/Subscriber';
// ...
public fetchModel(uuid: string = undefined): Observable<string> {
  if(!uuid) {
    return new Observable<TestModel>((subscriber: Subscriber<TestModel>) => subscriber.next(new TestModel())).map(o => JSON.stringify(o));
  }
  else {
    return this.http.get("http://localhost:8080/myapp/api/model/" + uuid)
            .map(res => res.text());
  }
}

.next()函数将在您的订阅者上调用。


2
我已经迁移到Angular 2.1.2。旧的方式似乎仍然得到支持。您能否详细说明为什么这是更好的解决方案,还是这是惯例?然后我将在我的代码中的所有位置进行更改,并重新接受..谢谢。 - Michail Michailidis
7
经过一个月的回顾,我认为两种方法都是有效的,主要区别在于Thierry的解决方案需要导入rxjs的of函数,例如import 'rxjs/add/observable/of' - Niel de Wet

13

这是您如何为静态数据创建简单的可观察对象。

let observable = Observable.create(observer => {
  setTimeout(() => {
    let users = [
      {username:"balwant.padwal",city:"pune"},
      {username:"test",city:"mumbai"}]

    observer.next(users); // This method same as resolve() method from Angular 1
    console.log("am done");
    observer.complete();//to show we are done with our processing
    // observer.error(new Error("error message"));
  }, 2000);

})

to subscribe to it is very easy

observable.subscribe((data)=>{
  console.log(data); // users array display
});

我希望这个答案对你有所帮助。我们可以使用HTTP调用代替静态数据。


你能把observable.subscripe中的拼写错误修改为observable.subscribe吗? - Sudharshan

5

截至2021年5月,从值获取Observable的新方法是:

导入:

import "rxjs/add/observable/of"
import { Observable } from "rxjs/Observable"

并像这样使用:

Observable.of(your_value)

3

您可以通过此方法从数据创建可观察对象,在我的情况下,我需要维护购物车:

service.ts

export class OrderService {
    cartItems: BehaviorSubject<Array<any>> = new BehaviorSubject([]);
    cartItems$ = this.cartItems.asObservable();

    // I need to maintain cart, so add items in cart

    addCartData(data) {
        const currentValue = this.cartItems.value; // get current items in cart
        const updatedValue = [...currentValue, data]; // push new item in cart

        if(updatedValue.length) {
          this.cartItems.next(updatedValue); // notify to all subscribers
        }
      }
}

Component.ts

export class CartViewComponent implements OnInit {
    cartProductList: any = [];
    constructor(
        private order: OrderService
    ) { }

    ngOnInit() {
        this.order.cartItems$.subscribe(items => {
            this.cartProductList = items;
        });
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接