จะสร้าง Observable จากข้อมูลคงที่คล้ายกับ http one ใน Angular ได้อย่างไร


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) ดังนั้นจึงมีการจัดการที่ราบรื่นในทั้งสองกรณี

คำตอบ:


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 () เป็นต้นเอกสาร API สำหรับ Observable ไม่ใช่สิ่งที่สะอาดที่สุด / ใช้งานง่ายที่สุดในตอนนี้! ขอบคุณ :)
Michail Michailidis

45
สิ่งหนึ่งหากคุณใช้เวอร์ชัน 6 คุณเคยimport { of } from 'rxjs';ใช้และใช้ofแทนObservable.of.
vip

2
สำหรับ v7.xx เชิงมุมไม่มีผลการรับเพื่อที่คุณต้องทำ.map() .pipe(map((res:any) => res.json()))ดูที่นี่: stackoverflow.com/a/35220045/986160
Michail Michailidis

64

เมื่อเดือนกรกฎาคม 2018 และการเปิดตัวRxJS 6วิธีใหม่ในการรับ Observable จากค่าคือการนำเข้าตัวofดำเนินการดังนี้:

import { of } from 'rxjs';

จากนั้นสร้างสิ่งที่สังเกตได้จากค่าดังนี้:

of(someValue);

โปรดทราบว่าคุณเคยต้องทำObservable.of(someValue)เช่นเดียวกับคำตอบที่ยอมรับในปัจจุบัน มีบทความดีใน RxJS 6 อื่น ๆ การเปลี่ยนแปลงเป็นที่นี่


ขอบคุณมากงานนี้
Sarah

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 ต้องการให้คุณนำเข้าofฟังก์ชันของ rxjs เช่น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 จากข้อมูลในกรณีของฉันฉันต้องดูแลตะกร้าสินค้า:

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;
        });
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.