2010-11-30 17 views
1

Je dois créer un composant auto-compléte en flex qui extrait les résultats auto-complétés d'une base de données distante en utilisant un service web. J'ai travaillé sur le webservice et l'interrogation. J'ai déjà fait des composants personnalisés dans le script d'action en étendant les VBox. Cependant, je n'arrive pas à comprendre comment générer la fenêtre contextuelle censée s'afficher sous la saisie de texte dans ma zone de texte automatique.Comment créer un composant automatique personnalisé dans Flex?

Actuellement, je suis en utilisant quelque chose comme

PopUpManager.addPopUp(popup, parentComponent); 

Ma classe popup étend VBox et étend la méthode createChildren comme suit

protected override function createChildren():void 
{ 
    for (var i:int = 0; i < results.length; i++) { 
    var itemC:UIComponent = 
     factory.getComponent(results[i]); 
    addChild(itemC); 
    itemC.addEventListener(MouseEvent.CLICK, 
     getClickFunction(i)); 
} 

private function getClickFunction(index:int):Function { 
    return function (event:MouseEvent):void 
     { 
      selectedIndex = index; 
     }; 
} 

Malheureusement, lorsque le webservice récupère ses résultats et addPopUp est appelé, rien révéler.

Actuellement, la méthode factory.getComponent exécute ce code

public function getComponent(user:Object):UIComponent 
{ 
    var email:Label = new Label(); 
    email.text = user.email; 
    var name:Label = new Label(); 
    name.text = user.displayName; 
    var vbox:VBox = new VBox(); 
    vbox.addChild(name); 
    vbox.addChild(email); 
    return vbox; 
} 

Répondre

0

Enfin, je compris comment utiliser le contrôle de la liste et je me suis arrêté à l'aide d'une usine pour produire des composants, à la place utiliser la fonction itemRenderer dans le contrôle de la liste. J'ai aussi utilisé cela pour remplacer la classe popup personnalisée, et j'ai ajouté une fonction de positionnement à appeler plus tard. En combinant ces choses, j'ai été en mesure d'obtenir la liste déroulante à afficher comme prévu. Il semble que certains composants ne fonctionnent pas bien en tant que pop ups.

Quoiqu'il en soit, le code pop-up de travail est

intérieur mon composant autocomplete qui étend HBox

dropDownList = new List(); 
dropDownList.itemRenderer = itemRenderer; 
dropDownList.dataProvider = results; 
dropDownList.labelFunction = labelFunction; 
dropDownList.rowCount = results.length; 
dropDownList.labelFunction = labelFunction==null ? 
    defaultLabelFunction : labelFunction; 
dropDownList.tabFocusEnabled = false; 
dropDownList.owner = this; 
PopUpManager.addPopUp(IFlexDisplayObject(dropDownList), DisplayObject(this)); 
callLater(positionDropDownList); 

Méthode dans le composant autocomplete (textInput est mon champ de texte)

public function positionDropDownList():void { 
    var localPoint:Point = new Point(0, textInput.y); 
    var globalPoint:Point = localToGlobal(localPoint); 
    dropDownList.x = globalPoint.x; 
    var fitsBelow:Boolean = parentApplication.height - globalPoint.y - textInput.height > dropDownList.height; 
    var fitsAbove:Boolean = globalPoint.y > dropDownList.height; 
    if (fitsBelow || !fitsAbove) { 
     dropDownList.y = globalPoint.y + textInput.measuredHeight; 
    } else { 
     dropDownList.y = globalPoint.y - dropDownList.height; 
    } 
} 

Le fonction de position était le code que j'ai emprunté http://hillelcoren.com/flex-autocomplete/

1

Je pense que vous devriez chercher quelqu'un qui a déjà mis en oeuvre. Bien que votre problème soit probablement lié au fait de ne pas positionner et dimensionner le composant avant d'appeler addPopup() même si nous vous avons aidé à le résoudre, vous avez encore beaucoup de travail à faire. (BTW appel super.createChildren dans votre override ou sinon de mauvaises choses vont arriver). Quoi qu'il en soit, vérifier cela:

http://www.adobe.com/cfusion/exchange/index.cfm?event=extensionDetail&extid=1047291

+0

Les implémentations existantes que j'ai trouvées ne fonctionnent pas avec le chargement à partir d'une source de données distante. Ils ont besoin des données de résultat immédiatement. Bon appel sur la chose super.CreateChildren. Je verrai si ça aide, c'est probablement ça. –

+0

@Bernard, alors qu'ils veulent une source de données immédiatement, vous pouvez vous inscrire à un événement comme showAutoComplete, et demander à l'auditeur d'aller parler au serveur obtenir des résultats de saisie semi-automatique, puis mettre à jour le fournisseur de données. Ou vous pouvez télécharger ce code source et le modifier pour vous permettre de le faire. Pas besoin de réinventer le composant entier à partir de zéro. – chubbsondubs

+0

J'avais modifié cela: http://hillelcoren.com/flex-autocomplete/ Et j'ai chargé les données de manière asynchrone, mais cela rendrait le menu déroulant avant que les données soient disponibles car il n'était pas conçu pour l'attendre. Quoi qu'il en soit, il est un peu trop tard, je dois le faire fonctionner, j'ai juste besoin de rendre le backend plus intelligent sur les résultats. Je posterai ma solution dès que j'y reviendrai. Merci. –