2009-08-26 8 views
1

Je me demande comment y parvenir dans Flex.Script Flex et événement Question

Fondamentalement, j'ai activé le glisser-déposer dans certains de mes contrôles de liste.

<mx:DataGrid id="dg1" width="100%" height="100%" dataProvider="{xmllcData}" 
      dropEnabled="true" dragDrop="dg1_dragDropHandler(event)"> 
</mx:DataGrid> 

Dans la fonction événement dg1_dragDropHandler, je les codes suivants:

private function dg1_dragDropHandler(evt:DragEvent):void 
{ 
    // Perform some actions here... 
    // ....... 

    // Show Message to Confirm. 
Alert.show('Proceed?', 'Title', Alert.YES | Alert.NO, null, handleAlert, null, Alert.YES); 
} 

private function handleAlert(evt:CloseEvent):void 
{ 
    if (evt.detail == Alert.YES) 
{ 
    // Perform the functions as necessary 
} 
else 
{ 
    // Execute the script to prevent the dropping of the object. 
    // How can I call the DragEvent.preventDefault(); function from here? 
} 

}

Dans les codes ci-dessus, je veux appeler le preventDefault() sur la fonction alertHandler depuis la D'autres scripts après l'appel de l'événement Alert.show dans l'événement dg1_dragDropHandler seraient exécutés simultanément avec alert.show.

Comment serais-je capable de référencer l'événement DragEvent de l'événement dg1_dragDropHandler de l'événement alertHandler?

Répondre

1

Au lieu de spécifier votre fonction d'écouteur, handleAlert(), en tant que fonction normale, vous pouvez utiliser une fonction anonyme. Écrivez votre code comme ceci:

private function dg1_dragDropHandler(evt:DragEvent):void 
    { 
    // Perform some actions here... 
    // ....... 

    // Show Message to Confirm. 
    Alert.show('Proceed?', 'Title', 
       Alert.YES | Alert.NO, 
       null, 
       function(evt:CloseEvent) { 
        if (evt.detail == Alert.YES) { 
         // Perform the functions as necessary 
        } 
        else { 
         // Execute the script to prevent the dropping of the object. 
         // Now you have access to the evt:DragEvent! 
        } 
       }, 
       null, Alert.YES); 
      } 
    } 

Lorsque vous utilisez une fonction anonyme, vous avez toujours accès à toutes les variables dans votre portée actuelle. Cela signifie que vous pouvez toujours accéder à la variable evt: DragEvent. Comme Glenn l'a dit, je ne sais pas si cela va résoudre votre problème d'action par défaut.

0

Vous souhaitez probablement stocker les détails de l'événement dropEvent dans une variable locale. Ensuite, lorsque vous voulez faire votre partie "preventDefault", accédez simplement à l'objet événement et faites votre magie.

Vous ne savez pas exactement pourquoi vous voulez éviter cela. Je ne comprends pas très bien cette partie. Tous les autres auditeurs de l'événement ne se termineraient-ils pas alors que le programme attend que vous disiez OUI/NON à l'alerte?

+0

preventDefault est destiné à empêcher l'opération dragDrop si la condition n'est pas remplie. Comme vous pouvez le voir, j'ai placé une fonction limitative Alert.show pour confirmer auprès de l'utilisateur si l'opération doit continuer * malgré la condition. Si l'utilisateur clique sur NO, je n'ai aucune idée de la façon dont alertHandler serait capable de gérer la fonction preventDefault qui n'est disponible que pour dragEvent. – Angelo

+0

Ce que je dis est que je m'attends à ce que lorsque vous cliquez sur "NON" sur l'alerte, il est déjà trop tard. Le problème est, je crois que vous avez affaire à plusieurs piles d'appels. Pendant que la boîte de dialogue d'alerte s'affiche, je m'attends à ce que vos autres piles d'appels s'exécutent et terminent l'événement. Peut-être que ce que vous voulez faire autoriser la baisse, mais si "NON" est sélectionné, vous supprimez la baisse immédiatement. – Glenn

+0

Oui, vous avez raison. Les autres piles d'appels sont exécutées immédiatement. Si la case No est sélectionnée, empêchez la suppression en appelant preventDefault de l'événement. Mais si vous pouviez seulement continuer la même chose à partir de alertHandler, comment référeriez-vous le dragEvent alors? – Angelo

0

Quelles autres parties du callstack fonctionnent ici? Vous pouvez empêcher tout événement dans la chaîne d'événements en appelant event.stopImmediatePropergation(); sur la première ligne de votre dragDropHandler (en supposant que l'écouteur a une priorité plus élevée que les autres dans la chaîne). Vous devrez ensuite répliquer manuellement les opérations de glisser-déposer sur confirmation, ce que je ne suis pas sûr mais que vous pourriez obtenir en utilisant la méthode doDrag() du DragManager.

DragManager.doDrag() langauge reference

0

Vous avez absolument raison que l'alerte sera sauté vers le haut de manière asynchrone par rapport à l'envoi DragEvent d'origine. Puisque vous ne voulez pas que le comportement de grille de données par défaut entre en action à ce stade, vous devez appeler preventDefault() à la réception de l'événement, puis lancer votre panneau d'alerte. Puis, dans la branche de succès de votre gestionnaire d'alerte, vous pouvez essayer de réécrire (lancer un nouveau) DragEvent. Utilisez une variable locale pour suivre les détails de l'événement d'origine afin de pouvoir cloner() ou simplement créer un nouvel événement avec les mêmes propriétés. Fondamentalement, vous interceptez et interrompez le flux d'événements, puis essayez de le reprendre plus tard.

N'avez pas essayé moi-même, mais c'est ce que j'explorerais en premier.

0

Je ne l'ai pas essayé moi-même, mais empêcher le comportement par défaut immédiatement est le seul moyen d'empêcher la grille d'effectuer la copie ou le déplacement. Essayez d'empêcher le comportement par défaut et de maintenir l'événement de traînée. Ensuite, si votre utilisateur ne répond pas, vous avez déjà arrêté l'événement. Si l'utilisateur tape oui, vous pouvez (c'est la partie dont je ne suis pas sûr) redistribuer l'événement drop sur la grille. Espérons qu'il se comportera normalement. Pour placer l'événement dans votre gestionnaire Alert, vous pouvez simplement utiliser la propriété data de la fenêtre Event pour le suivre.

private function dg1_dragDropHandler(evt:DragEvent):void 
{ 
    // Perform some actions here... 
    // ....... 

    evt.preventDefault(); 

    // Show Message to Confirm. 
Alert.show('Proceed?', 'Title', Alert.YES | Alert.NO, null, handleAlert, null, Alert.YES).data = evt; 
} 

private function handleAlert(evt:CloseEvent):void 
{ 
    if (evt.detail == Alert.YES) 
{ 
     // Perform the functions as necessary 
    var dgEvt:DragEvent = Alert(evt.currentTartet).data; 
    var newDrag:DragEvent; //need a new event because the default behaviour on the old one is still prevented 
    //copy event values to new drag event 
    dg1.dispatchEvent(newDrag); 

} 
else 
{ 
     // Execute the script to prevent the dropping of the object. 
     // How can I call the DragEvent.preventDefault(); function from here? 
} 

Encore une fois, pas tout à fait sûr si cela va fonctionner, juste sur le dessus de ma tête. Bien sûr, vous devez supprimer le gestionnaire d'événement dragDrop personnalisé de votre grille avant de redistribuer le drag approuvé, sinon votre gestionnaire empêchera le défaut, puis afficher une alerte et répéter encore et encore.