【问题标题】:How to create an Observable from static data similar to http one in Angular?如何从类似于 Angular 中的 http 的静态数据创建 Observable?
【发布时间】:2016-05-15 04:02:24
【问题描述】:

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

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 时会发生这种情况)所以有两种情况下的无缝处理。

【问题讨论】:

    标签: typescript promise angular observable rxjs


    【解决方案1】:

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

    导入:

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

    并像这样使用::

    Observable.of(your_value)
    

    【讨论】:

      【解决方案2】:

      截至 2018 年 7 月和 RxJS 6 的发布,从值中获取 Observable 的新方法是导入 of 运算符,如下所示:

      import { of } from 'rxjs';
      

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

      of(someValue);
      

      请注意,您过去必须像当前接受的答案那样做Observable.of(someValue)。有一篇关于其他 RxJS 6 更改的好文章here

      【讨论】:

        【解决方案3】:

        这样你可以从数据中创建 Observable,在我的例子中我需要维护购物车:

        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;
                });
            }
        }
        

        【讨论】:

          【解决方案4】:

          这就是你如何为静态数据创建一个简单的 observable。

          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.subscipe 中的拼写错误更新为 observable.subscribe 吗
          【解决方案5】:

          也许您可以尝试使用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());
            }
          }
          

          【讨论】:

          • 太棒了!有效!我尝试了很多东西,比如 Observable.from() 等。Observable 的 API 文档在这一点上并不是最干净/最用户友好的!谢谢:)
          • 如果您使用的是第 6 版,您必须使用import { of } from 'rxjs'; 并使用of,而不是Observable.of
          • 对于 Angular v7.x.x,get 的结果中没有.map(),所以你需要做.pipe(map((res:any) =&gt; res.json()))。见这里:stackoverflow.com/a/35220045/986160
          【解决方案6】:

          自 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() 函数将在您的订阅者上调用。

          【讨论】:

          • 我已经迁移到 Angular 2.1.2.. 旧方式似乎仍受支持.. 您能否详细说明为什么这是一个更好的解决方案或者它是惯例?然后我将在我的代码中的所有地方更改它,我会重新接受..谢谢
          • @MichailMichailidis,经过一个月的回想,在我看来两者都同样有效,主要区别在于 Thierry 的解决方案要求您导入 rxjs 的 of 函数,例如 import 'rxjs/add/observable/of'
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-07-17
          • 2013-11-07
          • 2021-05-02
          • 2019-11-17
          • 2023-04-04
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多