Développement d'un gestionnaire de contacts (CManager) avec ActionScript Foundry (AS Foundry) - Partie 2
Date de publication : 15 avril 2009
Par
Wajdi Hadj ameur (ServeBox Open Source)
1. Gestion de la liste des contacts
1-1. Modification d'un contact
1-2. Ajout d'un contact
1-3. Suppression d'un contact
2. Création du moteur de recherche
2-1. Première étape : construire l'indexation
2-2. Seconde étape : effectuer la recherche
1. Gestion de la liste des contacts
1-1. Modification d'un contact
Pour continuer la réalisation du tutoriel nous allons poursuivre à partir du fichier zip téléchargeable
ici, celle-ci contient l'ensemble du code source de la partie 1 avec les fichiers necessaires à la partie 2 que l'on va compléter pendant ce tutoriel.
Pour importer ce projet dans votre workspace, il faudra refaire la même manipulation que dans la partie 1, suivez donc
cette procédure.
L'ajout, la modification et la suppression d'un contact utilisent la même procédure que pour la récupération de la liste de contacts, les seules différences sont dans le traitement de la réponse du service. Pour mettre en place ces fonctionnalités, il faut tout d'abord modifier MainView et son helper pour déclencher l'événement de mise à jour d'un contact.
. . .
< mx: HBox
x= " 800 "
styleName= " saveBox "
id= " saveBox "
moveEffect= " {Move} "
width = " 250 "
height = " 40 " >
< mx: Label text = " Save changes ? " / >
< mx: Button
icon= " {EmbeddedMedia.getInstance().saveContactImg} "
buttonMode= " true "
styleName= " btnTopContact "
width = " 30 "
height = " 30 "
click= " {helper.updateContact()} "
/ >
. . .
|
Quand l'utilisateur clique sur le bouton pour faire la mise à jour, la méthode updateContact dans MainViewHelper est appelée pour lancer le traitement par le contrôleur grâce à la méthode updateContact :
. . .
public function updateContact (): void
{
getMainView (). currentState = BTN_SAVE_VIEW_STATE;
if (getMainView (). leftSmartForm. isUpdate)
{
switchMode ();
var updatedContactVO : ContactVO = getCurrentContact ();
MainController. getInstance (). updateContact ( updatedContactVO );
}
}
public function getCurrentContact () : ContactVO
{
var dtLeft : DictionaryTable = getMainView (). leftSmartForm. source;
var dtRight : DictionaryTable = getMainView (). rightSmartForm. source;
var dtBottom : DictionaryTable = getMainView (). bottomSmartForm. source;
dtLeft. putAll ( dtRight );
dtLeft. putAll ( dtBottom );
var contactOut : ContactVO = ContactVO ( MapUtils. getObjectFromDictionaryTable ( dtLeft, ContactVO ) );
return contactOut;
}
. . .
|
Le contrôleur appelle le service distant en utilisant la classe ContactUpdateResponder :
. . .
public function updateContact ( pContactVO : ContactVO ) : void
{
var updatedContactTO : ContactTO = wrapContactVO ( pContactVO );
getMainBusinessDelegate (). updateContact ( new ContactUpdateResponder (), updatedContactTO );
}
. . .
|
Créer la classe ContactUpdateResponder qui traite la réponse du service distant et appelle le modèle pour le mettre à jour:
. . .
public class ContactUpdateResponder implements IBusinessResponder
{
public function ContactUpdateResponder ()
{
}
public function result (data : Object ): void
{
var contactVO : ContactVO = ContactTO ( ResultEvent ( data ). result ). contacts. getItemAt ( 0 ) as ContactVO;
MainController. getInstance (). getContactModel (). updateThisContact ( contactVO );
}
public function fault (info: Object ): void
{
Alert. show (" Error updating the contact ! " );
}
}
|
Le modèle met à jour la liste de contacts et notifie les « observers » qui vont rafraîchir l'affichage :
. . .
* *
* Mise à jour du contact ( en fonction du contactId )
* Déclenche l' événement indiquant que la liste de contact à changé
* * /
public function updateThisContact ( pContactVO : ContactVO ) : void
{
var idx : int = 0 ;
for each ( var contact : ContactVO in _contacts){
if ( contact. contactId = = = pContactVO. contactId )
{
_contacts. setItemAt ( pContactVO, idx );
_contacts. refresh ();
notifyObservers ( new ContactListNotification ( null ) );
break ;
}
idx+ + ;
}
}
. . .
|
1-2. Ajout d'un contact
L'ajout et la suppression, utilisent exactement le même processus sauf que le traitement est différent dans le modèle. Dans le cas de l'ajout d'un contact :
. . .
* *
* crée un nouveau contact dans _contacts
* Déclenche l' événement indiquant que la liste de contact à changé
* * /
public function createContact ( pContactVO : ContactVO ) : void
{
_contacts. addItem ( pContactVO );
_contacts. refresh ();
notifyObservers ( new ContactListNotification ( null ) );
}
. . .
|
1-3. Suppression d'un contact
Lors de la suppression d'un contact, on demande une validation grâce à la classe Alert :
public function confirmDeleteContact ( e : Event ) : void
{
Alert. show (" Do you really want to remove " + selectedContact. firstName. toString () + " " + selectedContact. lastName. toString () + " from your contact list ? " ,
" Remove " + selectedContact. firstName. toString () + " " + selectedContact. lastName. toString () + " : " ,
3 , null , deleteContact);
}
|
Dans le cas de la suppression d'un contact :
. . .
public function deleteThisContact ( pContactVO : ContactVO ) : void
{
var idx : int = _contacts. getItemIndex ( pContactVO );
var i : int = 0 ;
for each (var contact : ContactVO in _contacts)
{
if (contact. contactId = = pContactVO. contactId)
{
_contacts. removeItemAt ( i );
_contacts. refresh ();
notifyObservers ( new ContactListNotification ( null ) );
}
i+ + ;
}
}
. . .
|
2. Création du moteur de recherche
Le fonctionnement du « Search Tree » est composé de deux étapes distinctes :
premièrement, il faut indexer les données. « Search Tree » crée un graphe d'expressions de recherche et relie les mots aux objets qui les contiennent, d'après les options émises sur les éléments d'objet;
deuxièmement, l'arborescence de recherche est à même d'effectuer des recherches en parcourant le graphe d'après une chaîne de caractères qui lui a été soumise.
Cette technique est beaucoup plus performante qu'une recherche directe sur la collection, car le plus gros du travail est effectué durant la phase d'indexation. Plus la chaîne de caractères soumise est longue, plus le nombre de possibilités sur le graphe est mince.
2-1. Première étape : construire l'indexation
L'indexation est créée à l'aide des classes SearchTree et SearchProperty. Pour chaque propriété des objets de valeur à indexer, une SearchProperty doit être créée et un type d'indexation doit être défini. Les propriétés sont ensuite utilisées pour créer l'indexation.
. . .
public function refreshView () : void
{
baseContactView ();
initSearchTree ();
getMainView (). contactList. selectedItem = getContactModel (). getContacts ()[ 0 ] as ContactVO;
dispatchEvent (new Event (' selectedContactChange ' ) );
}
. . .
override public function update ( o : IObservable, n: Notification) : void
{
dispatchEvent ( new Event (" contactListChange " ) );
refreshView ();
}
. . .
public function initSearchTree () : void
{
_tree = new SearchTree ();
var searchProperties : Array =
[
new SearchProperty ( " firstName " , SearchProperty. INDEX_TYPE_CONTAINS ),
new SearchProperty ( " lastName " , SearchProperty. INDEX_TYPE_CONTAINS )
] ;
_tree. index ( getContactModel (). getContacts (). source , searchProperties );
}
. . .
|
Le type d'indexation a plus d'impact sur les performances que le nombre d'objets à indexer et sur lesquels la recherche est effectuée.
Le type d'indexation impactera sur les performances plus que sur le nombre d'objets à indexer ou à rechercher.
Le graphe de mots résultant d'une indexation à l'aide de INDEX_TYPE_CONTAINS sera plus complexes.
2-2. Seconde étape : effectuer la recherche
Pour effectuer la recherche, nous utilisons simplement la méthode de recherche avec une String comme critère de recherche.
. . .
[ Bindable (" contactListChange " )]
public function get getContactList () : Array
{
if ( getMainView (). filterTextInput. text = = null | | getMainView (). filterTextInput. text . length < 1 )
{
return getContactModel (). getContacts (). source;
} else {
var searchResult : Array = _tree. search ( getMainView (). filterTextInput. text ). values ();
return searchResult;
}
}
. . .
|
On déclenche l'événement getContactList lors de la saisie dans DelayTextInput :
. . .
< elements: DelayTextInput
width = " 100% "
id= " filterTextInput "
change= " helper.dispatchEvent( new Event('contactListChange') ); "
delay= " 200 " / >
. . .
|
En remplissant le champ de recherche en haut à gauche de l'application, la liste de contacts est filtrée.
Vous pouvez télécharger le code source de l'application finale
ici.
Licence AS Foundry et Maven Flex Plugin : Open Source Apache 2
Copyright : ServeBox.org - Open Source