Làm thế nào để tạo một Observable từ dữ liệu tĩnh tương tự như http một trong Angular?


121

Tôi đang có một dịch vụ có phương thức này:

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

trong hàm tạo của thành phần, tôi đang đăng ký như thế này:

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

Điều này hoạt động nếu một đối tượng đến từ máy chủ nhưng tôi đang cố gắng tạo một đối tượng có thể quan sát được sẽ hoạt động với lệnh subscribe()gọi đã cho cho một chuỗi tĩnh (điều này xảy ra khi testModelService.fetchModel()không nhận được uuid) để có cách xử lý liền mạch trong cả hai trường hợp.

Câu trả lời:


151

Có lẽ bạn có thể thử sử dụng ofphương thức của Observablelớp:

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
Điều đó thật tuyệt! Nó đã làm việc! Tôi đã thử nhiều thứ như Observable.from (), vv .. Tài liệu API cho Observable không phải là sạch nhất / thân thiện với người dùng nhất tại thời điểm này! Cảm ơn :)
Michail Michailidis

45
Một điều nếu bạn đang sử dụng phiên bản 6, bạn phải import { of } from 'rxjs';và sử dụng ofthay vì Observable.of.
vip

2
Đối với Angular v7.xx không có .map()kết quả của get nên bạn cần làm .pipe(map((res:any) => res.json())). Xem tại đây: stackoverflow.com/a/35220045/986160
Michail Michailidis

64

Kể từ tháng 7 năm 2018 và việc phát hành RxJS 6, cách mới để lấy một Giá trị có thể quan sát được là nhập oftoán tử như sau:

import { of } from 'rxjs';

và sau đó tạo giá trị có thể quan sát được, như sau:

of(someValue);

Lưu ý rằng bạn đã từng phải làm Observable.of(someValue)như trong câu trả lời hiện được chấp nhận. Có một bài viết hay về các thay đổi khác của RxJS 6 ở đây .


Cảm ơn bạn rất nhiều, điều này hiệu quả
Sarah

19

Mọi thứ dường như đã thay đổi kể từ 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());
  }
}

Các .next()chức năng sẽ được gọi vào thuê bao của bạn.


2
Tôi đã di chuyển sang Angular 2.1.2 .. Cách cũ dường như vẫn được hỗ trợ .. Bạn có thể vui lòng giải thích tại sao đây là giải pháp tốt hơn hay đó là quy ước? Sau đó tôi sẽ thay đổi nó trong tất cả các nơi trong mã của tôi và tôi sẽ chấp nhận lại ..Thanks
Michail Michailidis

7
@MichailMichailidis, với một tháng nhìn lại, có vẻ như với tôi cả hai đều là giá trị ngang nhau, sự khác biệt chính là giải pháp mà Thierry đòi hỏi bạn phải nhập các ofchức năng của rxjs, giống nhưimport 'rxjs/add/observable/of'
Niel de Wet

12

Đây là cách bạn có thể tạo một dữ liệu tĩnh có thể quan sát được đơn giản.

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

Tôi hy vọng câu trả lời này là hữu ích. Chúng tôi có thể sử dụng cuộc gọi HTTP thay vì dữ liệu tĩnh.


bạn có thể cập nhật các typo từ observable.subscripe để observable.subscribe
Sudharshan

3

Bằng cách này, bạn có thể tạo Có thể quan sát từ dữ liệu, trong trường hợp của tôi, tôi cần duy trì giỏ hàng:

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;
        });
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.