将 属性 作为参数传递并在打字稿的函数内部更新它

Pass a property as parameter and update it inside the function in typescript

单行问题:是否可以将 属性 作为参数传递给函数并在函数本身中更新它?

场景

我的 ionic 项目中有一个配置文件 class,它打开了几个绑定到其中的属性(姓名、性别、电子邮件等)的模式。所有这些方法都是相同的,唯一不同的是在模态关闭后在哪里设置响应。

一个例子:

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();
  }

我有6个函数和这个一样,唯一不同的是属性,也就是函数里的consumed/set。


问题

这个视图可能会在收到其他属性后的几个月内增长,它们将做完全相同的事情,其中​​将添加 属性,这将导致过多的代码重复。

我的想法是让它面向对象,这样维护起来会更容易。我还在学习打字稿,我不知道它是否有类似于 java 反射的东西,这种更新将是小菜一碟。

我的梦想世界是这样的(大致来说):

  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)
  }

到目前为止我发现了什么

通过 Whosebug 中的几篇文章,我开始了解通用 in keyof 运算符,但我能够获取值但无法将其设置回 属性 作为参数出现。

我查看了 typescript documentation 和其他帖子以了解它,但我找不到专门将值设置回 属性 的内容。

我发现的最接近的 当外部变量是数字时,用户可以在其中递增外部变量。我试过用字符串这样做但是当我这样做时它声明我的类型在尝试将值设置回它时不能用作 indes 类型,尽管在发送它时它工作得很好(我改变了 属性 到下面示例中的任何一个):

我尝试在代码中实现的这种类型的交互是否可以通过打字稿实现?还是我做错了什么我没发现?

解决方案

正如@Cerbrus 在下面的回答中所教导的,这是(更加整洁、美观和可维护的)代码。

  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();
  }

你很接近。

查看您的原始代码,您试图在回调中在 this 上设置 属性。

您只需指定 classPropertythis 的键:

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();
}

然后你调用它,使用你想要更新的 key:

await this.changeField('name', ChangeNameModalPage)

(您的 IDE 应该会为您提供关于该参数的建议)

如果 this 范围在 changeField 函数和 onDidDismiss 回调之间发生变化,您可以使用 keyof MyObjectType 而不是 keyof this 来使用正确的类型。