2017-05-28 22 views
6

Đối với ứng dụng truyền thông xã hội, tôi có một bộ sưu tập các đối tượng nguồn cấp dữ liệu được tham chiếu bằng ID của chúng bằng cách sử dụng AngularFire 2. Khi mỗi ID này có dữ liệu liên quan được lấy từ cơ sở dữ liệu lưu trữ các đối tượng nguồn cấp dữ liệu thực, tôi muốn cập nhật đối tượng quan sát có thể hiển thị một tập hợp các đối tượng nguồn cấp dữ liệu trong HTML của tôi. Đó là một chuỗi sự kiện khá khó hiểu, vì vậy hãy để tôi tóm tắt nó cho bạn.Ionic 3 - Cập nhật có thể quan sát với dữ liệu không đồng bộ

Step-by-step cách tiếp cận

  1. displayFeed() được gọi ngay trước khi NavController tải các thành phần feed trên trang Main.
  2. displayFeed() tải mục twiner, về cơ bản là mục hồ sơ người dùng và sau đó lưu trữ hồ sơ người dùng trong biến số userProfile.
  3. Khi cấu hình người dùng được tải, toàn cầu feedCards Quan sát được đặt bằng loadFeed(), trả về một mảng quan sát được.
  4. loadFeed() sử dụng giá trị id của đối tượng toàn cầu userProfile để tải danh sách tham chiếu nguồn cấp dữ liệu được lưu trữ trong hồ sơ người dùng.
  5. Ảnh chụp nhanh này sau đó được đăng ký và biến số feed cục bộ được đặt bằng danh sách kết quả của tham chiếu nguồn cấp dữ liệu.
  6. loadFeed trả về đối tượng quan sát trong đó danh sách tham chiếu feed được ánh xạ theo dữ liệu mà mỗi nguồn cấp dữ liệu tham chiếu chứa.
  7. pullFeedData(number) có tham chiếu đến đối tượng nguồn cấp dữ liệu và trả về có thể quan sát được với dữ liệu nguồn cấp dữ liệu được liên kết.

gì Works

  • alert(JSON.stringify(feedData)); cảnh báo đúng đối tượng feed

  • Về cơ bản tất cả mọi thứ khác.

gì không hoạt động

  • feed.map(... không cập nhật các mảng thức ăn vì pullFeedData(number) kéo và trả về feedData không đồng bộ. Do đó, alert(JSON.stringify(data)); trong các cảnh báo displayFeed()[null].

feed.ts

userProfile:any; 
    feed: FirebaseListObservable<any>; 
    feedData: FirebaseObjectObservable<any>; 

    feedCards: Observable<any[]>; 

    constructor(public db: AngularFireDatabase, public nativeStorage: NativeStorage) {} 

    displayFeed():void { 
     this.nativeStorage.getItem('twiner').then((res) => { 
       this.userProfile = res; 
       this.feedCards = this.loadFeed(); 
       this.feedCards.subscribe((data)=>{ 
        alert(JSON.stringify(data)); 
       }) 
     }); 
    } 

    loadFeed():Observable<any[]> { 
     var feed; 
     this.feed = this.db.list('/twiners/' + this.userProfile.id + '/feed', { preserveSnapshot: true }); 
     this.feed.subscribe((snapshots)=>{feed = snapshots}); 
     return Observable.of(feed.map((snapshot) => { 
       this.pullFeedData(snapshot.val()).subscribe((feedData)=>{ 
        alert(JSON.stringify(feedData)); 
        return feedData; 
       }); 
     })).delay(1000); 
    } 

    pullFeedData(twine:number):any { 
     return this.db.object('/twines/' + twine, { preserveSnapshot: true }); 
    } 

feed.html

<ion-content fullscreen scroll="true" overflow-scroll="true"> 
     <ion-card *ngIf="feedCards | async">feedCards exist</ion-card> 
     <twine-feed-card *ngFor="let feedCard of feedCards | async" 
      [data]="feedCard" 
     ></twine-feed-card> 
</ion-content> 

Tóm tắt

feed.map không cập nhật feed với đối tượng nguồn cấp dữ liệu vì dữ liệu mới đang được kéo không đồng bộ. Tôi cần một sửa chữa cho việc này.

Cảm ơn bạn!

+0

bạn đã thử chạy nó bên trong khu ..? (Tôi đã từng sử dụng listobservables, bây giờ tôi sử dụng bộ phát sự kiện để đạt được chức năng thời gian thực này) –

+0

@RajaYogan Bạn có nhớ nhắc lại cách sử dụng chức năng này trong các vùng không? Tóm lại, tôi không biết đó là gì. –

+0

Không có probs .. bạn có nhận được dữ liệu ở đây trong một cảnh báo ..? this.feedCards.subscribe ((dữ liệu) => { cảnh báo (JSON.stringify (dữ liệu)); }) –

Trả lời

6

Quan sát đã đăng ký không trả lại giá trị. Nó trả về một đối tượng Subscription mà bạn có thể sử dụng để hủy đăng ký sau này.

Bạn có thể sử dụng switchMap để chuyển từ lần đầu tiên có thể quan sát sang lần tiếp theo trong khi gọi và trả lại giá trị. Ngoài ra, bạn có thể sử dụng forkJoin sẽ gọi một loạt các quan sát và chờ cho đến khi mảng giá trị được trả về trong đăng ký. Khai báo đầu tiên feed biến lớp dưới dạng Observable.

feed: Observable<any>; 

Sau đó, trong bạn loadFeed():Observable<any[]>

return this.feed.switchMap((snapshots) => { 
      let observableArray = []; 
      snapshots.forEach(snapshot =>{ 
       observableArray.push(this.pullFeedData(snapshot.val())); 
      }); 
      return Observable.forkJoin(observableArray) 
     }) 
+0

Cuối cùng, mã của tôi hoạt động với phương thức forEach sau câu trả lời của bạn. Cảm ơn nhiều!! –

Các vấn đề liên quan