TypeScript - چگونه Angular میتواند متدهای موجود در یک سرویس فرزند که با useClass تزریق شده است را «ببیند»؟
من یک سری کامپوننت Angular داشتم که بیشتر کدهایشان مشابه بود، بنابراین یک کامپوننت ایجاد کردم تا آن کدهای تکراری را در خود جای دهد، عمدتاً متدهای عمومی برای کار با دادهها از سمت سرور و مدیریت آنها در فرمها. مجبور شدم یک سرویس انتزاعی ایجاد کنم تا این کار را انجام دهد، چون هر فرم از سرویس خود استفاده میکرد، اگرچه آنها بسیار مشابه بودند.
کامپوننت «والد» متدها برای مدیریت دادهها در سرویس را فراخوانی میکند (کامپوننت فرزند از والد گسترش مییابد، اگرچه انتزاعی نیست)، و نحوه ایجاد سرویس در فرزند این است که با این شناسۀ @Component یک «useClass» به سرویس فرزند اختصاص داده میشود، بنابراین بهعنوان سرویس والد ایجاد میشود، مثلاً provide: MotherService, useClass: ChildService («MotherService» یک کلاس انتزاعی است که همه متدهای استفادهشده در کامپوننت مشترک را اعلان میکند، «ChildService» آن را گسترش میدهد و متدهای آن را بهدرستی پیادهسازی میکند).
موضوع این است که در یکی از کامپوننتها که من آن را از کامپوننت والد توسعه میدهم، باید برخی متدهای اضافی از سرویس را فراخوانی کنم، زیرا این سرویس از چندین جدول در پایگاه داده استفاده میکند و سرویس والد فقط یک جدول اصلی را مدیریت میکند. من در متد مذکور super را فراخوانی کردم و سپس ادامه کد مورد نیازم را اضافه کردم، با استفاده از متدهایی که منحصر به سرویس فرزند بودند. کد همانطور که انتظار میرفت کار کرد، اما ترمینال برای هر متدی که فقط از سرویس فرزند است، خطا میدهد:
ERROR in src/app/.../child/child.component.ts(63,8): error TS2339: Property 'methodThatMotherDoesntHave' does not exist on type 'MotherService'.
کد به صورت عادی اجرا میشود، اما به نظر میرسد Angular انتظار دارد سرویس والد تمام متدهایی که فراخوانی میشوند را داشته باشد، چون تابعی که آن را فرا میخواند از کد موجود در خود کامپوننت والد صدا زده میشود، حدس میزنم?!? حتی VS Code متدها را به رنگ قرمز نشان میدهد و پیشنهاد میکند که باید ایجاد شوند ("Property 'methodThatMotherDoesntHave' does not exist on type 'MotherService'."). چگونه میتوانم اعلام کنم که این متدها در سرویس فرزند وجود دارند، که در واقع به جای سرویس والد تزریق میشود؟
من از زمان اینکه خطا کاملاً غیرمعمول است و خود کد دقیقاً همانطور که انتظار میرود اجرا میشود، تلاش نکردهام کد را بازنویسی کنم. کمی درباره انواع دیگر تزریق مانند "UseExisting" خواندهام، اما به نظر نمیرسید که فوراً کمکی کند.
جزء اصلی:
export class MotherComponent implements OnInit {
@Input() data: Data[];
constructor(
public fb: FormBuilder,
public service: MotherService,
...
) { }
public getData() {
this.service
.getData()
.pipe(take(1))
.subscribe(data => {
this.data = data;
...
});
}
...
}
کامپوننت فرزند:
@Component({
...
providers: [
{ provide: MotherService, useClass: ChildService }
]
})
export class ChildComponent extends MotherComponent {
public data2: Data2[];
public getData() {
super.getData();
let data2: Data2[];
this.service
.getData2()
.pipe(take(1))
.subscribe(
data2 => {
this.data2 = data2;
);
}
...
}
خدمات انتزاعی:
@Injectable()
export abstract class MotherService {
constructor(public httpClient: HttpClientService) { }
getData() {
return new Observable<any>();
}
}
خدمات کودک:
@Injectable()
export class ChildService extends MotherService {
constructor(public httpClient: HttpClientService) { }
getData() {
return this.httpClient.get('blablabla/whatever/getData').pipe(
map((response: any) => {
if (!response) {
return [];
}
return response.Data.map(data => new Data().initializeWithJSON(data);
})
);
}
getData2() {
return this.httpClient.get('blablabla/whatever/getData2').pipe(
map((response: any) => {
if (!response) {
return [];
}
return response.Data2.map(data2 => new Data2().initializeWithJSON(data2);
})
);
}
}
من میخواهم با این کار خطاها را در ترمینال و در VS Code رفع کنم که انگولار تشخیص دهد متدهایی که فراخوانی میشوند در واقع به سرویس فرزند تعلق دارند، نه سرویس والد (شاید با ایجاد یک اعلامیه عجیب از آنها، شاید؟ اما نمیدانم چگونه این کار را انجام دهم).