Caching the Observables http data using Share and shareReplay Operators

Highlight לפוסט הנבחר

יש לנו הצגה של כל פוסט בנפרד כאשר לוחצים על כותרת הפוסט בקומפוננטת Alt Posts. השלב הבא הוא לסמן בצבע את הפוסט שעליו אנחנו עומדים. על מנת להשיג את זה נוסיף את ה-class של active לקישור שלנו.

<ul class="list-group">
    <a href="#" class="list-group-item list-group-item-action active"
        (click)="onSelectPost(post, $event)"
        *ngFor="let post of posts$ | async">
        {{ post.title }} ({{ post.categoryName }})
    </a>
</ul>

הבעיה כמובן היא שעכשיו כל השורות מודגשות. הפוסט שהמשתמש בחר נמצא במשתנה post$ בתוך DeclarativePostsService. נגדיר משתנה בקומפוננטה שמקבל את הפוסט הזה מה-service בשם selectedPost$. עכשיו נוכל לבדוק את ה-id של הפוסט שנבחר ולשים את ה-active רק על השורה הנכונה.

קובץ alt-posts.component.ts

selectedPost$ = this.postService.post$;

קובץ alt-posts.component.html

<ul class="list-group">
      <a href="#"
        [class]="{active: post.id === (selectedPost$ | async)?.id}"
        class="list-group-item list-group-item-action"
        (click)="onSelectPost(post, $event)"
        *ngFor="let post of posts$ | async">
        {{ post.title }} ({{ post.categoryName }})
      </a>
</ul>

shareReplay Caching

אן נעבור לעמוד Declarative posts ונסתכל על נתוני ה-network נראה שיש להו קריאה כפולה לקובץ categories.

זה קורה מכיוון שיש לנו קריאה אחת לקטגוריות כאשר אנחנו מייצרים את רשימת הפוסטים השלמה המשולבת על נתוני הקטגןריה וקריאה שנייה כאשר אנחנו רוצים את רשימת הקטגוריות לתיבת הבחירה. יש פה קריאה מיותר שמשפיעה על הביצועים. אם יש לנו כבר את המידע, אנחנו רוצים להשתמש בו. במקרה הזה נשתמש ב-Caching.

הקריאה לרשימת הקטגוריות מתבצעת בקובץ declarative-categories.service. כאן נרצה לשמור את המידע שהגיע על ידי שימוש באופרטור shareReplay. באופרטור נפרט כמה אובייקטים אנחנו רוצים לשמור, במקרה שלנו זה 1.

קובץ declarative-categories.service.ts

categories$ = this.http.get<Category[]>(`${this.baseUrl}/categories`)
.pipe(
  shareReplay(1)
);

אם נטען את הדף מחדש, נראה שעכשיו יש קריאה אחת לטבלת הקטגוריות.

בעמוד Alt Posts נראה שיש קריאה מרובה לטבלת הפוסטים, ניישם גם שם את shareReplay.

השימוש ב-shareReplay גורם לזה שלא תהיה קריאה מחדש להבאת הנתונים גם במעבר בין קומפוננטות. אם הקטגוריות נטענו בעמוד אחד, נראה שאין קריאה להבאת הנתונים מחדש גם במעבר לקומפוננטה אחרת.

share Caching

במקרה שנרצה שתהיה קריאה ל-API להבאת הנתונים בכל קומפוננטה מחדש, לא נשתמש ב-shareReplay אלא באופרטור share. במקרה הזה, ברגע שהסתיים subscribe לנתונים, תהיה קריאה מדש להבאה שלהם.

קובץ declarative-categories.service.ts

categories$ = this.http.get<Category[]>(`${this.baseUrl}/categories`)
  .pipe(
    share()
);

ניווט במאמר

מאמרים אחרונים

Weekly Tutorial