Ionic 4 手动覆盖 ion-select

Ionic 4 Manual Override of ion-select

您好,我需要在表单上使用 'select from list' 功能,但可以在需要时手动输入值。我一直在尝试 ion-select 但似乎没有办法进行手动覆盖。有办法吗?

谢谢

例如

    <ion-header>
  <ion-toolbar>
    <ion-title>kitlist testy</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
  <form [formGroup]="myForm">
  <ion-list>
    <ion-item>
      <ion-label stacked>Lens</ion-label>
      <ion-select placeholder="Select One">
          <ion-select-option value="f">Female</ion-select-option>
          <ion-select-option value="m">Male</ion-select-option>
        </ion-select>
      <ion-input type="text" formControlName='lens'></ion-input>
    </ion-item>
  </ion-list>


</form>
</ion-content>

会给

我希望用户能够添加他们自己的值 - 然后我将存储这些值。

谢谢

在 Sergey 的非常有用的回答之后,我尝试让它工作,但我被困在 inputAlert.onDidDismiss 这给了我

Expected 0 arguments, but got 1

这是我针对我的用例调整的代码:-

import { Component, OnInit } from "@angular/core";
import { FormBuilder, FormGroup } from "@angular/forms";
import { AlertController } from "@ionic/angular";

@Component({
  selector: "app-kitlist",
  templateUrl: "./kitlist.page.html",
  styleUrls: ["./kitlist.page.scss"]
})
export class KitlistPage implements OnInit {
  kitlist = ["lens1", "lens2", "Custom"];
  currentLens: any;
  myForm: FormGroup;

  constructor(
    private fb: FormBuilder,
    private alertController: AlertController
  ) {
    this.myForm = new FormGroup({});
  }

  ngOnInit() {
    this.myForm = this.fb.group({
      lens: ""
    });

    this.myForm.valueChanges.subscribe(console.log);
  }

  submitForm() {
    console.log("submit");
  }

  selectChanged(selectedLens) {
    if (selectedLens === "Custom") {
      this.inputCustomLensValue();
    } else {
      this.currentLens = selectedLens;
    }
  }

  async inputCustomLensValue() {
    const inputAlert = await this.alertController.create({
      header: "Enter your custom lens:",
      inputs: [{ type: "text", placeholder: "type in" }],
      buttons: [{ text: "Cancel" }, { text: "Ok" }]
    });

    inputAlert.onDidDismiss(data => {
      let customLensName: string = data.data.values[0];
      if (customLensName) {
        let indexFound = this.kitlist.findIndex(
          lens => lens === customLensName
        );
        if (indexFound === -1) {
          this.kitlist.push(customLensName);
          this.currentLens = customLensName;
        } else {
          this.currentLens = this.kit[indexFound];
        }
      }
    });
    await inputAlert.present();
  }
}

由于 ion-select 在引擎盖下使用警报控制器,我会直接利用它,我会在这里一起使用几个警报:

在您的模板中:

  <ion-item>
    <ion-label>Hair Color</ion-label>
    <ion-button slot="end" (click)="selectColors()">{{ currentOptionLabel }}
      <ion-icon slot="end" name="arrow-dropdown"></ion-icon>
    </ion-button>
  </ion-item>

您可以根据需要设置 ion-button 的样式。

现在,在您的 ts 文件中,我们可以导入 Alert Controller 并拥有其中的 2 个:一个用于 selecting 预制选项,另一个我们将创建输入类型的警报,以防我们的用户想要添加自定义值.

我在这里没有使用按钮的处理程序方法来确保 Angular 可以获取所有数据更改:

import { Component } from '@angular/core';
import { AlertController } from '@ionic/angular';

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.css'],
})
export class HomePage {

  public colorOptions: Array<{type: string, label: string, value: string}>

  public currentColorOptionIndex: number;

  public currentOptionLabel: string;

  constructor(public alertController: AlertController) {
    this.currentColorOptionIndex = 1;
    this.colorOptions = [
      {
        type: "radio",
        label: "Custom",
        value: "Custom"
      },
      {
        type: "radio",
        label: "Brown",
        value: "Brown",
      },
      {
        type: "radio",
        label: "Dark",
        value: "Dark",
      }
    ]
    this.currentOptionLabel = this.colorOptions[this.currentColorOptionIndex].label;
  }

  async selectColors() {
    const radioAlert = await this.alertController.create({
      header: 'Prompt!',
      inputs: this.colorOptions as any,
      buttons: [
        {
          text: 'Cancel',
          role: 'cancel',
          cssClass: 'secondary'
        }, {
          text: 'Ok'
        }
      ]
    });

    await radioAlert.present();

    radioAlert.onDidDismiss().then((data) => {
      let selectedValue = data.data.values;
      if (selectedValue === 'Custom') {
        this.inputCustomColorValue()
      };
      this.currentColorOptionIndex = this.colorOptions.findIndex(option => option.value == selectedValue)
      this.currentOptionLabel = this.colorOptions[this.currentColorOptionIndex].label;
    })
  }

  async inputCustomColorValue() {
    const inputAlert = await this.alertController.create({
      header: 'Enter your custom color:',
      inputs: [
        {
          type: 'text',
          placeholder: 'type in'
        }
      ],
      buttons: [
        {
          text: 'Cancel',
          role: 'cancel',
          cssClass: 'secondary'
        }, {
          text: 'Ok',
        }
      ]
    });

    await inputAlert.present();

    inputAlert.onDidDismiss().then((data) => {
      let customValue = data.data.values[0];
      let indexFound = this.colorOptions.findIndex(option => option.value == customValue)
      if (indexFound !== -1) {
        this.currentColorOptionIndex = indexFound
      } else {
        this.colorOptions.push(
          {
            type: 'radio',
            label: customValue,
            value: customValue,
          }
        )
        this.currentColorOptionIndex = this.colorOptions.length - 1;
      };
      this.currentOptionLabel = this.colorOptions[this.currentColorOptionIndex].label;
    })
  }

}

更新:添加了这样一个事实,即现在在最新的 Ionic 版本中(与使用旧 4 beta 的 Stackblitz 相比)onDidDismiss 钩子 returns 承诺并需要 onDidDismiss.then((data) => {})语法 vs onDidDismiss((data => {})