javascript - Bağımlılık tersine çevirme kullanarak döngüsel referans sorunu
Bu desen yaklaşımını kullanırken döngüsel referans sorunum var. TypeError: Class extends value undefined is not a constructor or null .
Tuhaf olan şu ki, eğer field.type.ts dosyasını src/constants.ts içine taşırırsam, hata vermiyor ve beklendiği gibi çalışıyor, fakat Unit Testlerde çökmeye neden oluyor. Eğer field.type.ts içeriğini kendi dosyasında bırakırsam, çöküyor.
Belki de bu bağımlılık tersine çevirme desenini doğru bir şekilde kullanmıyor/anlamıyor olabilirim. Muhtemelen bunu, Field.create(options: FieldOptions, fieldTypeMapping: FieldTypeToClassMapping) içinde FieldTypeToClassMapping parametresi geçirerek düzeltebilirim, ama bunun neden olduğunu anlamak istiyorum.
import { StringField } from './string.field.model';
import { IntegerField } from './integer.field.model';
...
export const FieldTypeToClassMapping = {
//Constructor of eg. StringField class so I can use `new FieldTypeToClassMapping[options.type](options)`;
[FieldTypeEnum.STRING]: StringField,
[FieldTypeEnum.INTEGER]: IntegerField,
};
//field/field.ts
import { FieldOptions } from 'src/interfaces/field.options.interface';
import { FieldTypeToClassMapping } from 'src/model/template/field.type.to.mapping.ts'
export abstract class Field {
value: any;
type: string;
errors: string[] = [];
public constructor(options: FieldOptions) {
this.value = options.value;
this.type = options.type;
}
public static create(options: FieldOptions): any {
try {
return new FieldTypeToClassMapping[options.type](options);
} catch (e) {
throw new Error(`Invalid field type: ${options.type}`);
}
}
}
//field/integer.field.ts
import { FieldOptions } from 'src/interfaces/field.options.interface';
import { Field } from './field.model';
export class IntegerField extends Field {
constructor(options: FieldOptions) {
super(options);
}
protected validateValueDataType() {
this.validateDataType(this.value, "value");
}
protected validateDefaultDataType() {
this.validateDataType(this.defaultValue, "defaultValue");
}
}
//field/service.ts
payload const postFields = [
{
type: "string", //FieldTypeEnum.STRING,
value: 'a name'
},
];
const postFields = [
{
type: "string",
value: "John",
},
{
type: "integer",
value: 32,
},
];
const fieldsArray = [];
postFields.forEach((item) => {
const field: Field = Field.create(item);
fieldsArray.addField(field);
});
return fieldsArray;
Cevap #1
create(options: FieldOptions) fonksiyonu Field sınıfı içinde tanımlıdır, ancak daha sonra Field'i genişleten bir sınıfın örneğini oluşturmaya çalışır.
Bence sorun tam da buradan kaynaklanıyor. Dosyalarınızın tamamının içeriğini bilmiyorum, ama herhangi bir field.type.ts dosyasının en üstünde Field'i import ettiğinizi hayal edebiliyorum. Ancak Field kendisinin herhangi bir somut uygulamasını örnekleyebildiği için, bunları bilmesi gerekir, bu yüzden Field'in içinde Field'i extend eden her şeyi import etmeniz gerekirdi.
Bağımlılık tersine çevirme desenini sorunuza bağlayacak kadar iyi bilmiyorum/anlamıyorum. Ancak verilen bilgilere göre, belki de ihtiyacınız olan Fabrika Desenidir?
Fonksiyonu create(options: FieldOptions) bir FieldFactory sınıfına taşıyabilirsiniz. Sizin create fonksiyonunuz zaten pratik olarak bir fabrika fonksiyonu.