מהו Observable ?
- במקור זהו Design Pattern מקובל ( הסבר מוויקיפדיה ) שיש לו מימושים בהרבה מאוד שפות , כמו שאפשר לראות באתר http://reactivex.io/languages.html
- הרעיון של תבנית התיכנות הזו, הוא שיש לנו אובייקט מסוים, שנגדיר אותו בתור "הנושא", ובנוסף אליו אנחנו מגדירים "צופים" שכל הזמן מסתכלים\עוקבים\צופים על הנושא, ברגע שמשהו בנושא משתנה ( בעגה המקצועית – יש שינוי של State , של מצב )
אז כל הצופים רואים את השינוי באופן אוטומטי.
- למה זה טוב ?
- זה לא מצריך להסתבך עם callbacks
- זה מאפשר לפתוח "ערוץ מידע" קבוע לכל מיני חיבורים למקורות מידע ( דאטאבייס, API, וכדומה ) כך שברגע ש-"נרשמנו" בתור "צופים" על הנושא, אז מרגע זה, אנחנו משוחררים מלבדוק כל הזמן את המצב של הנושא, אלא רק הגדרנו במקום מסוים, מה קורה כאשר הנושא משנה מצב (state), ומשם ואילך – הטיפול הוא באמצעות ה"צופה" שהגדרנו .
המחשה – Observable
- ניצור service
- נייבא פנימה גם את Observable מתוך rxjs/Observable
- ניצור משתנה שיכיל את המידע, מסוג Observable, ונשתמש ב-syntax של <> כדי להצהיר על הסוג הספציפי שיחזור.
המשתנה הזה, הוא ה-"צופה", כלומר הוא יכיל פונקציה שתדאג לדווח לנו בכל פעם שיש שינוי ב-state של המידע.
- ניצור פונקציה שמחזירה את המידע
- בתוך הפונקציה נשים בתוך המשתנה מסוג Observable שלנו, אובייקט חדש, מסוג Observable, עם פונקציה שמחזירה מידע
- לצורך הדוגמא בלבד, נשתמש ב-setTimeout, כדי להחזיר מידע חדש כל X זמן, ובעצם להדגים בזה, כיצד ה"צופה" מרגיש שהמידע השתנה, ומוסיף אותו לסט הנתונים.
- בקומפוננט
- נייבא את ה-Service שיצרנו
- ניצור משתנה שיקבל את התוכן
- ונרשום פקודה, ש-"נרשמת" לצפיה, בפונקציה של ה-service שמחזירה את הצופה.
- מה שיקרה הוא שהצופה יחזיר כל פעם מידע ברצף
כלומר בעצם יצרנו אפשרות ליצור רצף של מידע שמגיע.
--- The service file -----
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class BasicService {
data:Observable<Array<number>>;
constructor() {
}
getData() {
this.data = new Observable(observer => {
setTimeout(()=> {
observer.next(1);
},1000);
setTimeout(()=> {
observer.next(2);
},2000);
setTimeout(()=> {
observer.next(3);
},3000);
setTimeout(()=> {
observer.next(4);
},4000);
setTimeout(()=> {
observer.complete();
},5000);
});
return this.data;
}
}
----- the Component file -------
import { Component, OnInit } from '@angular/core';
import { BasicService } from './../../services/basicService2/basic.service';
@Component({
selector: 'app-use-observable2',
template: `
<h1>Observable Example</h1>
<ul>
<li *ngFor="let i of data">
{{ i }}
</li>
</ul>
`
})
export class UseObservable2Component implements OnInit {
data:any[] = [];
constructor(public basicService:BasicService) {
this.basicService.getData().subscribe(returnedData => {
console.log(returnedData);
this.data.push(returnedData);
});
}
ngOnInit() {
}
}