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


121

我正在使用此方法的服务:

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的情况下),因此在两种情况下都可以进行无缝处理。

Answers:


151

也许您可以尝试使用该类的of方法Observable

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

45
一件事,如果您使用的是版本6,则必须import { of } from 'rxjs';使用of而不是Observable.of
VIP

2
对于Angular v7.xx,没有.map()关于get的结果,因此您需要这样做.pipe(map((res:any) => res.json()))。看到这里:stackoverflow.com/a/35220045/986160
Michail Michailidis

63

从2018年7月开始,RxJS 6从中获取值的新方法是of像这样导入运算符:

import { of } from 'rxjs';

然后根据值创建可观察对象,如下所示:

of(someValue);

请注意,您以前必须Observable.of(someValue)在当前接受的答案中这样做。还有另RxJS一个很好的第6点的变化在这里


非常感谢,这项工作有效
莎拉

19

自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
@MichailMichailidis,回顾了一个月,在我看来都是同等有效的,主要区别在于Thierry的解决方案要求您导入ofrxjs 的功能,例如import 'rxjs/add/observable/of'
Niel de Wet

12

这样便可以为静态数据创建一个简单的可观察对象。

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

3

这样,您可以根据数据创建Observable,就我而言,我需要维护购物车:

服务

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;
        });
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.