angular - Synkronisering av Typescript-typer til Firebase-objektobservabler uten å miste funksjoner osv.


Jeg jobber med en Angular 2-app med Typescript, og jeg har stadig problemer med at jeg ikke ser ut til å kunne lagre objekttyper veldig enkelt når jeg synkroniserer data.

Jeg har manuelt satt egenskaper. I noen tilfeller fjerner jeg bare $exists(), $key, createdat-funksjonene og egenskapene for å kunne oppdatere dataene.

Finnes det en måte å sette en klasse fra et Firebase-objekt uten å endre det helt?

For et eksempel:

search$:FirebaseObjectObservable<ISearchQuery>;
search:ISearchQuery;

constructor(public af: AngularFire, public auth: AuthService){
  this.search$ = this.af.database.object(`/queries/saved/${auth.id}`);
  //THIS IS HOW I WANT TO DO IT
  this.search$.subscribe((data)=>{
    if(data.$exists()){
       this.search=data;           
    }
  });  

  //THIS IS WHAT I'VE RESORTED TO
  this.search$.subscribe((data)=>{
    if(data.$exists()){
      this.search.categories = data.categories;
      this.search.creators = data.creators;
      this.search.endDate = data.endDate;
      this.search.startDate = data.startDate;
      this.search.location = data.location;
     }
  });  
}

På den annen side, når jeg har synkronisert og oppdatert data, må jeg velge hver egenskap når jeg oppdaterer eller setter til Firebase. Jeg støter også på problemer hvis jeg synkroniserer direkte, da mister jeg klassefunksjoner også (siden Firebase-objekter har sitt eget sett med funksjoner i prototypen).

Finnes det en måte å unngå å velge egenskap for egenskap, eller en bedre måte å håndtere synkronisering av Firebase-objekter med Typescript på?

Svar #1

Det høres ut som du vil at AngularFire2 skal bevare Firebase-øyeblikksbildene. Som standard 'pakker den ut' øyeblikksbildene, og legger til $-prefikset egenskap og funksjon som du ikke ønsker.

Hvis du spesifiserer preserveSnapshot-alternativet, vil det ikke gjøre dette, og du kan kalle snapshot.val():

constructor(public af: AngularFire, public auth: AuthService) {

  this.search$ = this.af.database.object(`/queries/saved/${auth.id}`, {
    preserveSnapshot: true
  });
  this.search$.subscribe((snapshot) => {
    if(snapshot.exists()) {
       this.search = snapshot.val();
    }
  });
}

Og hvis du kommer til å trenge det senere, kan du alltid beholde øyeblikksbildet.

Når det gjelder ISearchQuery - som jeg antar er et grensesnitt - er verdien du mottar fra snapshot.val() et anonymt objekt. Det er trygt å kaste det til et grensesnitt som beskriver 'formen' til dataene, men hvis det grensesnittet inkluderer metoder, vil det ikke fungere fordi metodene ikke vil eksistere på det anonyme objektet. Hvis du har en klasse som implementerer det grensesnittet, bør du inkludere en konstruktør som aksepterer det anonyme objektet du mottar fra snapshot.val().

For eksempel:

this.search$.subscribe((snapshot) => {
  if(snapshot.exists()) {
    // Given SomeSearchQuery implements ISearchQuery
     this.search = new SomeSearchQuery(snapshot.val());
  }
});

Relaterte artikler