首页 > 解决方案 > 将属性作为参数传递并在 typescript 的函数内更新它

问题描述

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

设想

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

一个例子:

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 个与此相同的函数,唯一的区别是函数中使用/设置的属性。

配置文件视图


问题

这个视图可能会在几个月后长大,从现在接收其他属性,他们将做完全相同的事情,将添加属性,这将导致过多的代码重复。

我的想法是让它成为OO,这样维护会更容易。我还在学习打字稿,我不知道它是否有类似于 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)
  }

到目前为止我发现了什么

在 stackoverflow 的几篇文章中,我开始了解keyof运算符中的泛型,但我能够获取该值但不能将其设置回作为参数提供的属性。

我已经检查了打字稿文档和其他帖子以了解它,但我找不到专门将值设置回属性的东西。

我发现的最接近的是this post here,当外部变量为数字时,用户可以在其中增加外部变量。我试过用字符串这样做,但是当我这样做时,它表明我的类型在尝试将值设置回它时不能用作 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();
  }

标签: typescriptionic5

解决方案


你很亲密。

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

您只需要指定它classProperty是一个键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();
}

然后,您使用要更新的密钥调用它:

await this.changeField('name', ChangeNameModalPage)

(您的 IDE 应该会为您提供有关该参数可以是什么的建议)

如果函数和回调this之间的范围发生变化,您可以使用而不是使用正确的类型。changeFieldonDidDismisskeyof MyObjectTypekeyof this


推荐阅读