javascript - Hur man använder BehaviorSubject för att upptäcka förändringar


God dag allihopa. Snälla, jag har ett problem med att arbeta med BehaviorSubject. Jag försöker använda ett behavior subject i en delad tjänst som hämtar/uppdaterar användarinformation. Jag vill att när en användardata uppdateras, ska andra komponenter som prenumererar på den delade tjänsten också uppdateras.

Service.ts

  private userData= new BehaviorSubject<any>([]);
  data = this.userData.asObservable();


   customerData: any;


// this gets user data
getUserInfo(id){
  this.apiUrl = ` ${this.siteUrl}customers/${id}`;

  this.customerData = this.http.get(this.apiUrl);

   this.userData.next(this.customerData);
   return this.customerData;

}

//Update user data

updateCustomerData(id, customerDataUpdated){
  let headers = new HttpHeaders ({
    "Content-Type" : "application/json"
  });
  this.apiUrl = `${this.siteUrl}customers/${id}`;

  return new Promise((resolve, reject) => {
    this.http.put(this.apiUrl, customerDataUpdated, {headers} ).subscribe(
      response => {
        resolve(response);

        this.userData.next(this.customerData);

    },
    error => {
      resolve(error);

    }
    )
  });

Profil.ts

Vänligen berätta för mig hur jag använder BehaviorSubject här, så att om det finns någon uppdatering på någon komponent som prenumererar på den delade tjänsten, kommer även denna komponent att uppdateras. Tack

 customerData: any;  



  constructor( private WC: Service){
   }

     ngOnInit() {
       // get authenticated user id
        this.isUserLoggedIn = localStorage.getItem('currentUserId');


         this.WC.getUserInfo(this.isUserLoggedIn).subscribe((data)=>{
          this.customerData = data;  
        });


      }

redigera sida

  // Update user info
  async updateMethod(){

    let loading = await this.loadingCtrl.create({
      message: 'Updating...'
     });

     loading.present();
    this.isUserLoggedIn = localStorage.getItem('currentUserId');

    let customerDataUpdated = {
      "first_name": `${this.user.first_name}`,
      "last_name": `${this.user.last_name}`,
      "email": `${this.user.email}`,
      "username": `${this.user.username}`,
      "billing": {
     //   "first_name": `${this.user.billing.phone}`,
     //   "last_name": `${this.user.value.billing_last_name}`,
        "address_1": `${this.user.billing.address_1}`,
      //  "address_2": `${this.user.value.billing_address_2}`,
      //  "postcode": `${this.user.value.billing_postcode}`,
      //  "email": `${this.user.value.billing_email}`,
       "phone": `${this.user.billing.phone}`
      },

    }


   console.log('new update', this.user);  
   //update user data
   this.WC.updateCustomerData(this.isUserLoggedIn, customerDataUpdated).then((data)=>{


    this.changedetector.detectChanges();
      loading.dismiss();  


     });  
  }


  }

Svar #1

Låt mig förklara, du vill hämta getUserInfo beroende på användar-ID som är ett http-anrop. Därför triggas det bara en gång även om det är ett observerbart. Försök:

service.ts

private userData= new BehaviorSubject<any>([]);
userInfo$ = this.userData.asObservable();

// this gets user data
getUserInfo(id){
  this.apiUrl = ` ${this.siteUrl}customers/${id}`;
  return this.http.get(this.apiUrl).pipe(switchMap(userData) => {
     this.userData$.next(userData);
     return this.userInfo$;
  }) 
}

private fetchUserInfo(id){
  this.apiUrl = ` ${this.siteUrl}customers/${id}`;
  this.http.get(this.apiUrl).subscriber(data =>{
    this.userData$.next(userData);
  })
}

//Update user data

updateCustomerData(id, customerDataUpdated){
  let headers = new HttpHeaders ({
    "Content-Type" : "application/json"
  });
  this.apiUrl = `${this.siteUrl}customers/${id}`;
  return this.http.put(this.apiUrl, customerDataUpdated, {headers}).pipe(
      tap(response => this.fetchUserInfo(id))
    )
  });

Gör ändringar i edit-page.component.ts därefter för updateCustomerData eftersom det inte längre är ett löfte.

En varningsnotis: om du använder userInfo$ och skickar någon annan id till getUserInfo() så kommer det att påverka din Profile.ts-komponent. Eftersom de delar ett gemensamt observerbart objekt.

Svar #2

Var snäll och prova detta,

customerData: any;  


constructor( private WC: Service){ }

ngOnInit() {
//this will triger when data is changing
this.WC.data.subcribe(res => {

});

}

Relaterade artiklar