تايب سكريبت - كيفية تنفيذ Subject سلوكي باستخدام الخدمة في Angular 8
أنا جديد في Angular ولدي مشكلة.
أنا أقوم بإنشاء تطبيق يحتوي على عدة مكونات شقيقة. عندما أقوم بتحديث قيمة في أحد المكونات، لا يتم تحديث المكونات الأخرى. أعلم أنه لحل هذه المشكلة يجب أن أستخدم سلوك الموضوع. لكن كيف أقوم بتنفيذه مع خدمتي والمكونات وجميع القوالب؟
إليك شفرتي -
----------------------خدمتي---------------------------
//import
@Injectable()
export class CoachService {
apiURL = environment.apiURL;
constructor(private http: HttpClient ) { }
coachProfile(token :string)
{
return this.http.post<any>(this.apiURL+'/coach/profile_infos',{
token: token
})
}
updateProfile(info: any, token: string, us_id: string) {
return this.http.post<any[]>(this.apiURL + '/coach/update_profile', {
token: token,
us_id: us_id,
us_lang: info.us_lang,
us_firstname: info.us_firstname,
us_lastname: info.us_lastname,
us_sex: info.us_sex,
us_birthdate: info.us_birthdate,
us_national_number : info.us_national_number,
us_email: info.us_email,
us_gsm: info.us_gsm,
online_profile: info.online_profile,
us_address: info.us_address,
us_zip: info.us_zip,
us_city: info.us_city,
country:{
id: info.country.id
}
})
}
}
----------عنصر واحد-------------------
//import
//component decorator
export class CoordonneesComponent implements OnInit, OnDestroy {
private coachProfile;
token: string = localStorage.getItem('token');
us_id : string;
us_lang: string;
infos_profile: any;
online: any;
constructor(private translate: TranslateService,private coachService: CoachService, private router: Router) { }
ngOnInit() {
this.coachProfile=this.coachService.coachProfile(this.token)
.subscribe((data) => {
this.infos_profile = data.results;
this.online = this.infos_profile.online_profile;
this.translate.use(this.infos_profile.us_lang)
this.infos_profile.lang= this.infos_profile.us_lang;
});
.....
}
updateCoordonees() {
this.coachService.updateProfile(this.infos_profile, this.token, this.us_id)
.subscribe((data: any) => {
if(data.success && data.msg!=null)
{
// do something
}
else
{
// do something
}
},
(err) => {
// do something
});
}
ngOnDestroy() {
this.countrieList.unsubscribe();
this.coachProfile.unsubscribe();
}
}
الإجابة رقم 1
سأريك طريقة بسيطة:
@Injectable()
export class ProfileService {
private profileObs$: BehaviorSubject<Profile> = new BehaviorSubject(null);
getProfileObs(): Observable<Profile> {
return this.profileObs$.asObservable();
}
setProfileObs(profile: Profile) {
this.profileObs$.next(profile);
}
}
الآن عندما تقوم بتحديث شيء ما في أي مكان في التطبيق، يمكنك تعيين هذا التغيير بواسطة ProfileService وكل مشترك يستقبل التغيير. أوصي بأن تقوم بالاشتراك في ngOnInit.
ngOnInit() {
this.profileService.getProfileObs().subscribe(profile => this.profile = profile);
}
لا تنسَ أبدًا إلغاء الاشتراك من الكائنات القابلة للمراقبة لمنع تسرب الذاكرة!
هناك عدة طرق يمكنك القيام بذلك --> استخدم الاشتراك وقم بإلغاء الاشتراك في ngOnDestroy() أو استخدم موضوعًا آخر ومرره إلى takeUntil بهذه الطريقة:
unsubscribe$: Subject<boolean> = new Subject();
...
ngOnInit() {
this.profileService.getProfileObs()
.pipe(takeUntil(this.unsubscribe$))
.subscribe(profile => this.profile = profile);
}
ngOnDestroy() {
this.unsubscribe$.next(true);
this.unsubscribe$.complete();
}
الإجابة رقم 2
أولاً أنشئ BehaviourSubject
this._source = new BehaviourSubject<yourType>(initialValue);
this.source = this._source.asObservable();
قم بتعريف دالة لـ "تحديث" الـ BehaviourSubject
updateSource(newValue) {
this._source.next(newValue)
}
اشترك الآن في المكونات الخاصة بك في المصدر
this.service.source.subscribe();
لاحظ أن behaviourSubject يحتاج دائمًا إلى قيمة أولية ويصدر الأخيرة
المستندات: https://www.learnrxjs.io/subjects/behaviorsubject.html
إذا كنت تريد مشاركة البيانات من httpRequest يجب عليك استخدام عامل shareReplay() بدلاً من ذلك، يمكنك الاشتراك في httpRequest من مكونات مختلفة وسيتم تنفيذ الطلب مرة واحدة وسيتم مشاركة البيانات
الوثائق: https://www.learnrxjs.io/operators/multicasting/sharereplay.html
