1. समस्या

मैं अपने ब्लॉग के लिए बदलती भाषा का प्रवाह बनाने की कोशिश कर रहा हूं और संक्षेप में, यह इस तरह दिखेगा:

  1. उपयोगकर्ता एक बटन पर क्लिक करता है जो एक घटना को ट्रिगर करता है (Subject), यानी, भाषा बदल जाती है।
  2. इस भाषा परिवर्तन का उपयोग उस भाषा के आधार पर सही पृष्ठ के लिए Firebase को क्वेरी करने के लिए किया जाता है।

यदि मैं प्रत्येक चरण अलग से करता हूं और बाद में, उपयोगकर्ता भाषा बदलता है, तो क्वेरी ट्रिगर नहीं होगी क्योंकि यह नहीं जानता कि कोई घटना अभी हुई है। तो मेरा मानना ​​​​है कि यह किसी प्रकार की नेस्टेड सदस्यता/अवलोकन योग्य होना चाहिए। क्या मै गलत हु?

2. माई कोड सो फार

मैंने नेस्टिंग सब्सक्रिप्शन की कोशिश की है, लेकिन यह काम नहीं किया। मेरा मानना ​​​​है कि यह स्कोपिंग बग्स के कारण था। अभी, मैं यही कोशिश कर रहा हूं:

this.headerService.langChanged.pipe(
  map(
    (newLang: string) => {
      this.db
        .collection<AboutMePage>(
          this.aboutMeCollectionName, 
          ref => ref.where('lang', '==', newLang)
        )
        .valueChanges();
  })
)
  .subscribe(
    value => {
      this.aboutMe = value[0]
    }
  );

headerService.langChanged एक Subject<string> है।

क्या इस उपयोग के मामले के लिए कोई rxjs ऑपरेटर है? concat एक अच्छे उम्मीदवार की तरह लग रहा था, लेकिन यह पिछले Observable के समाप्त होने की प्रतीक्षा करता, जो इस मामले में नहीं है। और यह भी तथ्य है कि मुझे अगले अवलोकन पर पैरामीटर पास करना होगा ...

1
Philippe Fanaro 30 पद 2019, 22:43

2 जवाब

सबसे बढ़िया उत्तर

मुझे लगता है कि आपके लिए किसी भी concat, switchMap, merge, forkJoin, आदि का उपयोग करने के लिए वैध समाधान हैं। यह वास्तव में उन छोटी चीजों पर निर्भर करता है जो आप उनमें से चाहते हैं जैसे कि समवर्ती के रूप में। मैंने यहां forkJoin का उपयोग करके एक छोटा स्टैकब्लिट्ज उदाहरण एक साथ रखा: https://stackblitz.com/edit /angular-xyf8a6

आप कंसोल लॉग में प्रत्येक आंतरिक Observable के अलग-अलग समय देख सकते हैं ताकि यह सत्यापित किया जा सके कि forkJoin का उपयोग करके यह केवल सबसे धीमी गति से देखने योग्य है।

और सदस्यता के रूप में मेरे पास है:

this.langChanged
  .subscribe(newLang => {
    console.log(`language changed ${newLang}`);
    this.cancelLangChange.next();
    forkJoin(
      this.getUserName(newLang), 
      this.getUserBio(newLang), 
      this.getUserCreationDate(newLang)
    )
      .pipe(takeUntil(this.cancelLangChange))
      .subscribe(([username, bio, userCreationDate]) => {
        this.aboutMe.username = username;
        this.aboutMe.bio = bio;
        this.aboutMe.userCreationDate = userCreationDate;
      });
  });

मैंने एक दूसरा Subject cancelLangChange भी जोड़ा, जो forkJoin सदस्यता को रद्द करने के लिए है यदि कोई उपयोगकर्ता किसी अन्य भाषा का चयन करता है, जबकि वह अभी भी पहला परिवर्तन लोड कर रहा है।

2
Philippe Fanaro 31 पद 2019, 02:11

मैं मूल रूप से pipe और map का उपयोग करके इसे काम करने में कामयाब रहा। map ऑपरेशन पहले अवलोकन योग्य का उपयोग पूर्व के मापदंडों के आधार पर दूसरे को उत्पन्न करने के लिए करेगा। फिर हम नेस्टेड तरीके से सदस्यता लेते हैं, जो अंततः हमें वह डेटा देगा जो हम चाहते थे।

this.aboutMeSubscription = this.headerService.langChanged.pipe(
  map(
    (newLang: string) => {
      return this.db
        .collection<AboutMePage>(
          this.aboutMeCollectionName, 
          ref => ref.where('lang', '==', newLang)
        )
        .valueChanges();
  })
)
  .subscribe(
    langChangedAboutMeObs => {
      this.langChangedSubscription = langChangedAboutMeObs
        .subscribe(
          (value: AboutMePage[]) => {
            this.aboutMe = value[0];
          }
        );
    }
  );

मैंने अपने Subject को एक BehaviorSubject में भी बदल दिया है, इसलिए उपयोगकर्ता के कुछ भी करने से पहले ही एक प्रारंभिक मान उत्सर्जित कर दिया गया है। अंत में, ngOnDestroy को दोनों सदस्यताओं की सदस्यता समाप्त करना महत्वपूर्ण है।

0
Philippe Fanaro 30 पद 2019, 22:18