ionic5 - Skicka en egenskap som parameter och uppdatera den inuti funktionen i typescript
Problemet i en enda rad: Är det möjligt att skicka en egenskap som en parameter till en funktion och uppdatera den i själva funktionen?
Scenario
Jag har en profilklass i mitt Ionic-projekt som öppnar flera modaler som är knutna till egenskaperna i den (namn, kön, e-post, osv). Alla dessa metoder är samma, det enda som gör dem olika är var man sätter svaret efter att modalen stängts.
Ett exempel:
async changeName() {
const modal = await this.modalCtrl.create({
component: ChangeNameModalPage,
cssClass: 'default-modal',
componentProps: {
'content': this.name // get class property value
}
});
modal.onDidDismiss().then((modalDataResponse) => {
if (modalDataResponse.data !== null && modalDataResponse.data !== undefined) {
this.name = modalDataResponse.data; // set value back to class property
}
});
return await modal.present();
}
Jag har 6 funktioner som är samma som denna, den enda skillnaden är egenskapen som används/sätts i funktionen.
Problemet
Denna vy kommer förmodligen att växa på några månader från nu genom att ta emot andra egenskaper och de kommer att göra exakt samma sak, där egenskapen kommer att läggas till, vilket kommer att orsaka för mycket kodduplicering.
Min idé är att göra det objektorienterat så att underhållet skulle bli enklare. Jag lär mig fortfarande TypeScript och jag vet inte om det har något liknande Java reflection, där den här typen av uppdatering skulle vara mycket enkel.
Min drömvärld skulle vara denna (ungefär sagt):
async changeField(classProperty, modalPage) {
const modal = await this.modalCtrl.create({
component: modalPage, // the component that will be used
cssClass: 'default-modal',
componentProps: {
'content': classProperty // get current property value
}
});
modal.onDidDismiss().then((modalDataResponse) => {
if (modalDataResponse.data !== null && modalDataResponse.data !== undefined) {
classProperty = modalDataResponse.data; // set back the property value
}
});
return await modal.present();
}
async changeName() {
await this.changeField(this.name, ChangeNameModalPage)
}
async changePhone() {
await this.changeField(this.phone, ChangePhoneModalPage)
}
async changeEmail() {
await this.changeField(this.email, ChangeEmailModalPage)
}
Vad har jag hittat hittills
Genom flera inlägg på Stack Overflow kom jag att lära mig om den generiska in keyof-operatorn, men jag kan få värdet men inte sätta tillbaka det till egendomen som kommer som en parameter.
Jag har gått igenom TypeScript-dokumentationen och andra inlägg för att lära mig om det, men jag kan inte hitta något som specifikt återställer värdet till egenskapen.
Det närmaste jag har hittat var det här inlägget där användaren kan öka den externa variabeln när det är ett nummer. Jag har försökt göra det med en sträng men när jag gör det står det att min typ inte kan användas som en indextyp när jag försöker sätta tillbaka värdet till den, även om det fungerar helt fint när jag skickar det (jag ändrade egenskapen till any i exemplet nedan):
Är denna typ av interaktion i koden som jag försöker uppnå möjlig med TypeScript? Eller gör jag något fel som jag inte kan upptäcka?
Lösning
Som lärts ut av @Cerbrus i svaret nedan, här är koden (mycket mer prydlig, vacker och lätt att underhålla).
async changeName() {
await this.changeField('name', ChangeNameModalPage);
}
async changeBirthday() {
await this.changeField('birthday', ChangeBirthdayModalPage);
}
async changeCPF() {
await this.changeField('cpf', ChangeCPFModalPage);
}
async changePhone() {
await this.changeField('phone', ChangePhoneModalPage);
}
async changeEmail() {
await this.changeField('email', ChangeEmailModalPage);
}
async changeGender() {
await this.changeField('gender', ChangeGenderModalPage);
}
async changeField(classProperty: keyof this, modalPage) {
const modal = await this.modalCtrl.create({
component: modalPage,
cssClass: 'default-modal',
componentProps: {
'content': this[classProperty]
}
});
modal.onDidDismiss().then((modalDataResponse) => {
if (modalDataResponse.data !== null && modalDataResponse.data !== undefined) {
this[classProperty] = modalDataResponse.data;
}
});
return await modal.present();
}
Svar #1
Du var nära.
Tittar man på din ursprungliga kod försöker du sätta en egenskap på this i callbacken.
Du behöver bara ange att classProperty är en nyckel i this:
async changeField(classProperty: keyof this, modalPage) {
const modal = await this.modalCtrl.create({
component: modalPage, // the component that will be used
cssClass: 'default-modal',
componentProps: {
'content': this[classProperty] // get current property value
}
});
modal.onDidDismiss().then((modalDataResponse) => {
if (modalDataResponse.data !== null && modalDataResponse.data !== undefined) {
this[classProperty] = modalDataResponse.data; // set back the property value
}
});
return await modal.present();
}
Du kallar sedan det, med den nyckel du vill uppdatera:
await this.changeField('name', ChangeNameModalPage)
(Din IDE borde ge dig förslag på vad den parametern kan vara)
Om this-omfånget ändrades mellan changeField-funktionen och onDidDismiss-callbacken, kan du använda keyof MyObjectType istället för keyof this för att använda rätt typ.

