【问题标题】:Ionic 5 : How to close ion-select programmaticallyIonic 5:如何以编程方式关闭离子选择
【发布时间】:2021-11-09 11:50:06
【问题描述】:

在我的 ionic react 应用程序中,我在表单中使用 IonSelect。当下拉列表打开时,我需要在硬件后退按钮事件侦听器调用中以编程方式关闭 IonSelect 下拉列表。这是代码

export const SingleSelection: React.FC = () => { 
   const [gender, setGender] = useState<string>();
   
    useEffect(() => {
     
      document.addEventListener('ionBackButton', (ev: any) => {
         ev.detail.register(1000, async (processNextHandler: any) => {
           console.log('Handler B was called!');
    
           processNextHandler();
         });
      });
      return () => {
        console.log("use effect return");
      }
   }, [])

   return (
     <IonPage>
        <IonContent>
          <IonItem>
              <IonLabel>Gender</IonLabel>
              <IonSelect value={gender} placeholder="Select One" onIonChange={e => setGender(e.detail.value)}>
                 <IonSelectOption value="female">Female</IonSelectOption>
                 <IonSelectOption value="male">Male</IonSelectOption>
               </IonSelect>
           </IonItem>
         </IonContent>
      </IonPage>   
    );
};

更新:[已解决]:这是我更新后的完整代码,带有模态。在硬件后退按钮事件侦听器方法中,首先关闭离子选择(如果它保持打开状态),然后关闭模式

const ModalExample: React.FC = () => {
    const [showModal, setShowModal] = useState(false);
    const [gender, setGender] = useState<string>();

    useEffect(() => {
        document.addEventListener('ionBackButton', (ev: any) => {
            ev.detail.register(1000, async (processNextHandler: any) => {
                console.log('Handler B was called!');
                try {
                    console.log("close ion select");
                    const alert = await alertController.getTop();
                    if (alert) {
                        alert.dismiss();
                        return;
                    }
                    console.log("close modal")
                    const element = await modalController.getTop();
                    if (element) {
                        //element.dismiss();
                        setShowModal(false)
                        return;
                    }
                } catch (error) {
                    console.log(error);
                }
                processNextHandler();
            });
        });
        return () => {
            console.log("use effect return");
        }
    }, [])

    return (
        <IonContent>
            <IonModal isOpen={showModal} cssClass='my-custom-class'>
                <p>This is modal content</p>
                <IonItem>
                    <IonLabel>Gender</IonLabel>
                    <IonSelect value={gender} placeholder="Select One" onIonChange={e => setGender(e.detail.value)}>
                        <IonSelectOption value="female">Female</IonSelectOption>
                        <IonSelectOption value="male">Male</IonSelectOption>
                    </IonSelect>
                </IonItem>
                <IonButton onClick={() => setShowModal(false)}>Close Modal</IonButton>
            </IonModal>
            <IonButton onClick={() => setShowModal(true)}>Show Modal</IonButton>
        </IonContent>
    );
};

【问题讨论】:

    标签: reactjs ionic5 ion-select


    【解决方案1】:

    虽然按下硬件后退按钮会自动关闭 IonSelect 下拉菜单。如果这对您不起作用,这里有一个使用 useRef 钩子的解决方法:

    export const SingleSelection: React.FC = () => { 
        const [gender, setGender] = useState<string>();
        const selectRef = useRef<any>(null);
    
        useEffect(() => {
         
          document.addEventListener('ionBackButton', (ev: any) => {
             ev.preventDefault(); // TO PREVENT THE CLOSING OF MODAL
             ev.detail.register(1000, async (processNextHandler: any) => {
               console.log('Handler B was called!');
               selectRef.current.close() // SEE HERE
    
    
               // HERE YOU CAN NOW CLOSE THE MODAL
    
               processNextHandler();
             });
          });
          return () => {
            console.log("use effect return");
          }
       }, [])
    
        return (
             ...
             <IonSelect ref={(ref: any) => selectRef.current = ref} value={gender} placeholder="Select One" onIonChange={e => setGender(e.detail.value)}>
                <IonSelectOption value="female">Female</IonSelectOption>
                <IonSelectOption value="male">Male</IonSelectOption>
             </IonSelect>
             ....
        
            );
    
    };
    

    【讨论】:

    • TypeError: selectRef.current.close is not a function 显示此错误
    • ...hardware back button automatically closes the IonSelect dropdown ,是的,你是对的,但是我的下拉菜单在模式上,使用硬件后退按钮我关闭了模式,但下拉菜单保持打开状态,所以我必须以编程方式关闭它
    • 先尝试添加ev.preventDefault(),因为关闭模态后当前引用可能不可用
    • 我必须在关闭模式之前关闭下拉菜单,因此我尝试使用 selectRef.current.close() ,但显示错误 TypeError: selectRef.current.close is not a function,可能 IonSelect 没有名为 close 的函数
    • 是的,这就是为什么我要求您添加ev.preventDefault() 以便在按下后退按钮时停止关闭您的模式,然后您可以关闭离子选择。这是因为如果先关闭模式,那么 selectRef 将是未定义的,这就是函数未定义的原因。
    【解决方案2】:

    我已经找到了解决方案。使用alertController IonSelect 下拉菜单可以通过编程方式关闭,

    import { alertController } from "@ionic/core";
    .....
    
    useEffect(() => {
    
        document.addEventListener('ionBackButton', (ev: any) => {
          ev.detail.register(1005, async (processNextHandler: any) => {
            console.log('Handler D was called!');
            const alert = await alertController.getTop();
            console.log(alert);
            if (alert) {
              alert.dismiss();
              return;
            }
            processNextHandler();
          });
        });
        return () => {
          console.log("use effect return");
        }
      }, [])
    

    【讨论】:

      最近更新 更多