Tutoriel : Utilisation d'un serveur DataSnap REST avec une application et FireDAC

De RAD Studio
Aller à : navigation, rechercher

Remonter à Tutoriels Bases de données et LiveBindings


Suivez ce tutoriel pour construire une application de base de données multiniveau avec le framework DataSnap. Le serveur est une application web qui accède aux données d'une base de données InterBase. Le client est une application multi-périphérique qui inclut un module client DataSnap REST. Le client utilise le protocole HTTP pour se connecter au serveur et échanger des données JSON par le biais d'interfaces REST.

Ce tutoriel utilise les technologies suivantes :

  • Base de données : Interbase
  • Framework d'accès aux bases de données : FireDAC
  • Format de données : JSON
  • Architecture Client/Serveur : REST
  • Protocole de communication : HTTP
  • Ensemble de données en-mémoire côté client : FireDAC TFDMemTable
  • Technologie IU : LiveBindings visuel

Vous pouvez trouver une démo Delphi à l'emplacement C:\Utilisateurs\Public\Documents\Embarcadero\Studio\22.0\Samples\Delphi\DataSnap\FireDACJSONReflect

Création de l'application DataSnap REST

  1. Créez un nouveau projet :
    • Choisissez Fichier > Nouveau > Autre dans le menu principal.
    • Accédez au noeud Serveur DataSnap dans la colonne de gauche, sous le noeud Projets C++Builder ou Projets Delphi.
    • Sélectionnez Application DataSnap REST et appuyez sur OK.
    • Spécifiez le type de l'application :
      1. Sélectionnez Application autonome et appuyez sur Suivant.
      2. Choisissez l'une des options suivantes :
        • Application VCL
        • Application FireMonkey
      3. Conservez les valeurs par défaut concernant l'utilisation d'un protocole de communication HTTP et appuyez sur Suivant.
        Remarque : Cliquez sur Tester le port pour vérifier que le port est libre.
      4. Laissez les options sélectionnées par défaut, Classe de méthodes serveur et les exemples si vous voulez avoir un exemple de déclaration de méthodes sur le serveur.
      5. Choisissez TDataModule pour implémenter entièrement la classe serveur et cliquez sur Suivant. Cette option ajoute une fiche dans laquelle vous pouvez placer les composants FireDAC pour la connexion à la base de données.
      6. Choisissez l'emplacement du projet et le nom du dossier projet, et cliquez sur Terminer.
  2. Changez la propriété Caption de la fiche Form1 en ServerForm.
    ServerFormDSTutorial.png
  3. Cliquez sur l'élément de menu principal Fichier > Tout enregistrer.
  4. Enregistrez l'unité FormUnit1 en tant que ServerUnit, l'unité WebModuleUnit1 en tant que WebModuleUnit1, l'unité ServerMethodsUnit1 en tant que ServerMethodsUnit1, et enregistrez le projet en tant que MyServerProj.

Composants serveur DataSnap clés

Lorsque vous créez l'application DataSnap REST, tous les composants DataSnap nécessaires sont automatiquement ajoutés à l'unité WebModuleUnit1.

WebModuleDSApplication.png

Les composants principaux sur l'unité WebModuleUnit1 sont :

Le composant TDSServer est le coeur logique de l'application serveur DataSnap. Il contient les méthodes Start et Stop pour démarrer et arrêter le serveur. Vous avez besoin d'un seul composant TDSServer par application serveur.

Le composant TDSServerClass représente une classe serveur. Le serveur DataSnap crée et détruit automatiquement les instances des classes serveur.

Le protocole de communication HTTP permet d'établir la communication entre le client et le serveur.

Ajout de composants FireDAC au module serveur

Ajoutez les composants suivants à l'unité ServerMethodsUnit1 :

  • Un composant TFDConnection. Définissez sa propriété Name sur "FDConnectionEMPLOYEE".
    • Cliquez avec le bouton droit sur le composant et cliquez sur Editeur de connexion. La fenêtre Editeur de connexion FireDac s'ouvre à l'endroit où vous devez définir les paramètres de connexion.
    • Sélectionnez IB dans le menu déroulant pour le champ ID du pilote.
    • Définissez le chemin de la base de données Interbase : C:\Utilisateurs\Public\Documents\Embarcadero\Studio\22.0\Samples\Data\EMPLOYEE.GDB.
    • Définissez User_Name et Password. Les valeurs par défaut de ces paramètres sont User_Name = sysdba et Password = masterkey.
    • Cliquez sur OK pour enregistrer les modifications.
    • Sur l'inspecteur d'objets, changez la propriété LoginPrompt en False.
    • Définissez la propriété Connected sur True.
    • Conseil : Vous pouvez utiliser l'explorateur de données pour déposer un nouveau composant TFDConnection. Sur l'explorateur de données, allez à InterBase > EMPLOYEE, cliquez sur le composant et déposez-le sur la fiche.
  • Un composant TFDPhysIBDriverLink pour établir la connexion à une base de données InterBase.
  • Un composant TFDGUIxWaitCursor.
  • Trois composants TFDQuery.
    • Cliquez avec le bouton droit sur le composant TFDQuery et cliquez sur Editeur de requête pour ouvrir la fenêtre de l'éditeur de requête FireDAC pour introduire les instructions SQL détaillées plus loin.
    • Renommez un composant en FDQueryDepartmentNames et introduisez l'instruction SQL suivante : select dept_no, department from department et cliquez sur OK. Cette requête renvoie la liste des numéros et des noms de département. Le résultat de cette requête est utilisé par le client pour construire la liste des départements. Afin de récupérer ces informations, l'application client doit appeler la méthode serveur "GetDepartmentNames".
    • Renommez le deuxième composant en FDQueryDepartment et introduisez l'instruction SQL suivante : select * from department where DEPT_NO = :DEPT et cliquez sur OK.
    • Renommez le dernier composant en FDQueryDepartmentEmployees et introduisez l'instruction suivante : select * from employee where dept_no = :DEPT et cliquez sur OK.
      Remarque : Les deux dernières requêtes - FDQueryDepartment et FDQueryDepartmentEmployees - sont utilisées pour récupérer davantage d'informations détaillées pour un département donné dans les tables DEPARTMENT et EMPLOYEE. Les informations renvoyées par les deux requêtes sont exposées aux clients via la méthode serveur "GetDepartmentEmployees".
  • Un composant TFDStanStorageJSONLink.
  • Un composant TFDStanStorageBinLink.

ServerMethodsUnit1 contient l'implémentation de deux méthodes simples appelées EchoString et ReverseString, qui renvoient la valeur donnée sous la forme d'un paramètre dans des états inversés respectifs normaux. Ce sont juste des méthodes exemple.

Dans cet exemple, nous avons ajouté de nouvelles méthodes à ServerMethodsUnit1 pour récupérer les données JSON à partir de la base de données exemple InterBase EMPLOYEE sous-jacente, et le serveur expose ces méthodes au client.

Méthode serveur "GetDepartmentNames"

  • Dans Delphi :

Cette méthode obtient tous les départements et donne un TFDJSONDataSets en tant que résultat.

{$METHODINFO ON}
public
    { Public declarations }
function GetDepartmentNames: TFDJSONDataSets;
{$METHODINFO OFF}

Utilisez l'achèvement de classe en appuyant sur CTRL-MAJ-C pour créer un stub pour cette fonction dans la section implementation.

Ecrivez le code de la fonction que vous venez d'ajouter.

//GetDepartmentNames
function TServerMethods1.GetDepartmentNames: TFDJSONDataSets;
begin
  // Clear active so that query will reexecute.
  FDQueryDepartmentNames.Active := False;
  Result := TFDJSONDataSets.Create;
  // The "TFDJSONDataSetsWriter" class provides static "ListAdd" method.
  // It uses reflection to convert results of the query into "TFDJSONDataSets".
  TFDJSONDataSetsWriter.ListAdd(Result, FDQueryDepartmentNames);
end;

La fonction renvoie un nouveau type de données : TFDJSONDataSets. Pour utiliser ce type, vous devez inclure une unité requise dans la section uses de l'interface : Data.FireDACJSONReflect. Cette unité est nécessaire à la fois dans la déclaration de la classe et dans la section implementation.

  • Dans C++ :

Cette méthode obtient tous les départements et donne un TJSONObject en tant que résultat.

La déclaration de la méthode se trouve dans le fichier ServerMethodsUnit1.h.

public:     // User declarations
    TJSONObject* GetDepartmentNames();

Le code de la méthode se trouve dans le fichier ServerMethodsUnit1.cpp.

TJSONObject* TServerMethods1::GetDepartmentNames() {
    FDQueryDepartmentNames->Close();

    TFDJSONDataSets *ds = new TFDJSONDataSets();
    TFDJSONDataSetsWriter::ListAdd(ds, FDQueryDepartmentNames);

    TJSONObject *obj = new TJSONObject();
    TFDJSONInterceptor::DataSetsToJSONObject(ds, obj);
    return obj;
}

Vous devez inclure ces fichiers d'en-tête dans le fichier ServerMethodsUnit1.h :

  1. # include <System.Json.hpp> //type de données TJSONObject
  2. # include <Data.FireDACJSONReflect.hpp> //type de données TFDJSONDataSets

Méthode serveur "GetDepartmentEmployees"

Utilisez cette méthode pour récupérer davantage d'informations détaillées pour un département donné dans les tables DEPARTMENT et EMPLOYEE en utilisant FDQueryDepartment et FDQueryDepartmentEmployees. Nous pouvons obtenir les données à partir des deux requêtes en utilisant une seule méthode. A cet effet, nous avons besoin de créer deux constantes.

  • Dans Delphi :

Incluez les constantes sous une instruction uses dans la section implementation.

const
  sDepartment = 'Department';
  sEmployees = 'Employees';

Incluez cette déclaration de méthode dans la déclaration de classe de la section interface.

{$METHODINFO ON}
public
    { Public declarations }
function GetDepartmentEmployees(const AID: string): TFDJSONDataSets;
{$METHODINFO OFF}

Utilisez l'achèvement de classe en appuyant sur CTRL-MAJ-C pour créer un stub pour cette fonction dans la section implementation.

Ecrivez le code de la fonction que vous venez d'ajouter.

function TServerMethods1.GetDepartmentEmployees(const AID: string): TFDJSONDataSets;
begin
  // Clear active so that query will reexecute.
  FDQueryDepartmentEmployees.Active := False;
  FDQueryDepartment.Active := False;
  FDQueryDepartment.Params[0].Value := AID;
  FDQueryDepartmentEmployees.Params[0].Value := AID;

   // Create dataset list
  Result := TFDJSONDataSets.Create;
   // Add departments dataset
  TFDJSONDataSetsWriter.ListAdd(Result, sDepartment, FDQueryDepartment);
    // Add employees dataset
  TFDJSONDataSetsWriter.ListAdd(Result, sEmployees, FDQueryDepartmentEmployees);
end;

Ces deux méthodes sont utilisées par une application client afin de recevoir des informations relatives aux départements. Nous obtenons d'abord la liste des noms de département et leurs IDs (méthode GetDepartmentNames). Lorsqu'un client sélectionne un département dans la liste, les informations détaillées relatives au département et à ses employés sont alors renvoyées par la deuxième méthode serveur (GetDepartmentEmployees).

  • Dans C++ :

Placez la déclaration des constantes dans le fichier ServerMethodsUnit1.cpp.

const System::String sEmployees = "Employees";
const System::String sDepartment = "Department";

La déclaration de la méthode se trouve dans le fichier ServerMethodsUnit1.h.

public:     // User declarations
    TJSONObject* GetDepartmentEmployees(System::UnicodeString AID);

Le code de la méthode se trouve dans le fichier ServerMethodsUnit1.cpp.

// Get a Department and all Employees in the department.  Return TJSONObject.
TJSONObject* TServerMethods1::GetDepartmentEmployees(System::UnicodeString AID)
{
    FDQueryDepartmentEmployees->Active = false;
    FDQueryDepartment->Active = false;
    FDQueryDepartment->Params->operator[](0)->Value = AID;
    FDQueryDepartmentEmployees->Params->operator[](0)->Value = AID;

    // Create dataset list
    TFDJSONDataSets *ds = new TFDJSONDataSets();
    // Add departments dataset
    TFDJSONDataSetsWriter::ListAdd(ds, sDepartment, FDQueryDepartment);
    // Add employees dataset
    TFDJSONDataSetsWriter::ListAdd(ds, sEmployees, FDQueryDepartmentEmployees);

    TJSONObject *obj = new TJSONObject();
    TFDJSONInterceptor::DataSetsToJSONObject(ds, obj);
    return obj;
}

Méthode serveur "ApplyChangesDepartmentEmployees"

Utilisez cette méthode pour envoyer les mises à jour des données du client et mettre à jour la base de données sous-jacente. Cette méthode ne renvoie pas de valeur. Cette méthode utilise un paramètre TFDJSONDeltas. Ce type est également inclus dans l'unité Data.FireDACJSONReflect. Nous pouvons mettre à jour plusieurs tables en une seule opération. Voici le code source.

  • Dans Delphi :
{$METHODINFO ON}
public
    { Public declarations }
    procedure ApplyChangesDepartmentEmployees(const ADeltaList: TFDJSONDeltas);
{$METHODINFO OFF}

Utilisez l'achèvement de classe en appuyant sur CTRL-MAJ-C pour créer un stub pour cette fonction dans la section implementation.

Ecrivez le code de la fonction que vous venez d'ajouter.

// Update department and employees using deltas
procedure TServerMethods1.ApplyChangesDepartmentEmployees(
  const ADeltaList: TFDJSONDeltas);
var
  LApply: IFDJSONDeltasApplyUpdates;
begin
  // Create the apply object
  LApply := TFDJSONDeltasApplyUpdates.Create(ADeltaList);
  // Apply the department delta
  LApply.ApplyUpdates(sDepartment, FDQueryDepartment.Command);
  if LApply.Errors.Count = 0 then
    // If no errors, apply the employee delta
    LApply.ApplyUpdates(sEmployees, FDQueryDepartmentEmployees.Command);
  if LApply.Errors.Count > 0 then
    // Raise an exception if any errors.
    raise Exception.Create(LApply.Errors.Strings.Text);
end;
  • Dans C++

Placez la déclaration des constantes dans le fichier ServerMethodsUnit1.h.

public:     // User declarations
    void ApplyChangesDepartmentEmployees(TJSONObject* AJSONObject);

Le code de la méthode se trouve dans le fichier ServerMethodsUnit1.cpp.

void TServerMethods1::ApplyChangesDepartmentEmployees(TJSONObject* AJSONObject)
{
    TFDJSONDeltas *LDeltas = new TFDJSONDeltas();
    TFDJSONInterceptor::JSONObjectToDataSets(AJSONObject, LDeltas);

    TFDJSONErrors *errs = new TFDJSONErrors();

    // Apply the department delta
    TFDJSONDeltasApplyUpdates::ListApplyUpdates(LDeltas, sDepartment,
        FDQueryDepartment->Command, errs);

    // If no errors, apply the employee delta
    if (errs->Count == 0) {
        TFDJSONDeltasApplyUpdates::ListApplyUpdates(LDeltas, sEmployees,
            FDQueryDepartmentEmployees->Command, errs);
    }

    // Raise an exception if any errors.
    if (errs->Count > 0) {
        throw new Exception(errs->Strings->Text);
    }

}

Avant de créer l'application client, exécutez le serveur :

  • Choisissez Exécuter > Exécuter sans déboguer dans le menu principal.
  • Cliquez sur le bouton Démarrer. Vous pouvez minimiser le dialogue ServerForm qui s'affiche.

Cette étape est très importante car vous avez besoin d'une connexion au serveur afin de créer les classes client nécessaires pour récupérer les données du serveur.

Création de l'application client

  1. Pour créer l'application client dans le même groupe de projets que l'application serveur, procédez comme suit :
    • Dans le Gestionnaire de projets, cliquez avec le bouton droit sur ProjectGroup.
    • Sélectionnez l'option Ajouter un nouveau projet.
    • Dans l'élément Projets Delphi ou Projets C++Builder, sélectionnez Application multi-périphérique et cliquez sur OK.
    • Choisissez Application vide et cliquez sur OK.
    • Cliquez sur l'élément de menu principal Fichier > Nouveau > Autre.
    • Depuis le noeud Serveur DataSnap de la colonne de gauche, sélectionnez Module client DataSnap REST et appuyez sur OK.
      RESTClientModuleMenu.png
    • Spécifiez le type du module :
      • Conservez la valeur sélectionnée par défaut -- Serveur local -- et appuyez sur Suivant.
      • Conservez la valeur sélectionnée par défaut -- Serveur autonome DataSnap -- et appuyez sur Suivant.
      • Conservez la valeur par défaut pour les paramètres de connexion et appuyez sur Terminer.
        • Remarque : Cliquez sur Tester la connexion pour vérifier la connexion avec le serveur. Si le serveur n'est pas en cours d'exécution, vous ne pourrez pas terminer l'expert.
      L'expert génère maintenant ClientModuleUnit et ClientClassesUnit.
  2. Changez la propriété Caption de la fiche Form2 en ClientForm.
  3. Cliquez sur l'élément de menu principal Fichier > Tout enregistrer.
  4. Enregistrez l'unité Unit2 en tant que ClientUnit, l'unité ClientModuleUnit1 en tant que ClientModuleUnit1, l'unité ClientClassesUnit1 en tant que ClientClassesUnit1, et le projet en tant que MyClientProj.
  5. Enregistrez le groupe de projets dans DSServerExample.
  6. Remplissez la fiche client avec les contrôles et les composants suivants :
    • Un composant TButton. Changez la propriété text en Get Departments.
    • Un composant TButton. Changez la propriété text en Apply Updates.
    • Un composant TListView. Changez la propriété name en ListViewDepartments.
    • Un composant TStringGrid. Changez la propriété name en StringGridDepartment.
    • Un composant TStringGrid. Changez la propriété name en StringGridEmployee.
    • Un composant TFDMemTable. Changez la propriété name en FDMemTableDepartments. Cet ensemble de données est seulement utilisé pour le stockage de données en lecture seule avec la liste des numéros des départements et leurs noms.
      • Vous avez besoin des définitions des champs de la table TFDMemTable afin de les lier à la conception. Sur le panneau Structure, cliquez avec le bouton droit sur FieldDefs et cliquez sur Ajouter un élément pour ajouter deux nouveaux éléments : 0 - DEPARTMENT, et 1 - DEPT_NO.
        • Remarque : Les types de champs ne sont pas importants, mais les noms et les définitions de champs doivent correspondre aux champs des ensembles de données reçus du serveur.
    • Un composant TFDMemTable . Changez la propriété name en FDMemTableDepartment.
      • Changez la propriété CachedUpdates en True.
    • Un composant TFDMemTable . Changez la propriété name en FDMemTableEmployee.
      • Changez la propriété CachedUpdates en True.
    • Un composant TFDStanStorageJSONLink.
    • Un composant TFDStanStorageBinLink.

Utilisation du Concepteur LiveBindings

Utilisez les liaisons dynamiques visuelles pour lier des données à des contrôles visuels.

  • Accédez à Voir > Concepteur LiveBindings pour ouvrir la fenêtre Concepteur LiveBindings.
  • Changez la propriété ItemAppearance > ItemAppearance du TListView en ListItemRightDetail pour ajouter la propriété Item.Detail au TListView.
  • Liez le champ DEPARTMENT du FDMemTableDepartments à Item.Text.
  • Liez le champ DEPT_NO du FDMemTableDepartments à Item.Detail.
  • Liez le StringGridDepartment à FDMemTableDepartment.
  • Liez le StringGridEmployee à FDMemTableEmployee.
RestClientModuleApp.png

Appel des méthodes serveur sur le client

Vous devez appeler les méthodes serveur sur l'application client afin de récupérer les données.

Remarque : Si vous changez la définition des méthodes serveur, vous devez redémarrer le serveur. Après le redémarrage du serveur, vous devez également actualiser le proxy, cliquer avec le bouton droit sur le composant TDSRestConnection de ClientModuleUnit et cliquer sur Générer les classes client DataSnap dans le menu contextuel.

GetDepartmentNames

Dans Delphi :

Dans la fiche ClientUnit, incluez ClientModuleUnit1. Ajoutez l'unité à l'instruction uses dans l'interface ou dans la section implementation.

Remarque : Pour ajouter une unité avec l'expert, accédez à Fichier > Utiliser l'unité.... La fenêtre Utiliser l'unité s'ouvre à l'endroit où vous devez sélectionner l'unité que vous souhaitez inclure dans le fichier en cours.

Pour utiliser le type de données TFDJSONDataSets, vous devez ajouter une unité requise à l'instruction uses de la section implementation : Data.FireDACJSONReflect.

private
    { Private declarations }
    procedure GetDepartmentNames;
procedure TForm2.GetDepartmentNames;
var
    //To use this type you need to include a new unit in the uses section: Data.FireDACJSONReflect.
    LDataSetList: TFDJSONDataSets;
begin
    // It empties the memory table of any existing data before adding the new context.
    FDMemTableDepartments.Close;
    // Get dataset list containing Employee names
    LDataSetList := ClientModule1.ServerMethods1Client.GetDepartmentNames;
    // Reads the first and only dataset, number 0.
    FDMemTableDepartments.AppendData(
      TFDJSONDataSetsReader.GetListValue(LDataSetList, 0));
      //It uses a reader from The "TFDJSONDataSetsWriter" class to populate the memory table from the dataset list class.

    FDMemTableDepartments.Open;
end;

Implémentez l'événement OnClick pour appeler la procédure GetDepartmentNames.

procedure TForm2.Button1Click(Sender: TObject);
begin
  GetDepartmentNames; //Calling this method populates the TListView.
end;
  • Dans C++ :

Incluez les fichiers d'en-tête suivants dans le fichier ClientUnit.h :

  1. # include <Mémoire> // Cet en-tête définit les utilitaires généraux permettant de gérer la mémoire dynamique.
  2. # include <Data.FireDACJSONReflect.hpp>
  3. # include <DataSnap.DSClientREST.hpp>
  4. # include <ClientModuleUnit1.h>

La déclaration de la méthode se trouve dans le fichier ClientUnit.h.

public:     // User declarations
    void GetDepartmentNames();

Ce code se trouve dans le fichier ClientUnit.cpp.

void TForm2::GetDepartmentNames() {
    // Gets JSON data from the server using "ClientModule1" class that was generated with the "DataSnap REST Client Module" wizard.
    TJSONObject* LJSONObject
        (ClientModule1->ServerMethods1Client->GetDepartmentNames());
    std::auto_ptr<TFDJSONDataSets>LDataSets(new TFDJSONDataSets());
    // Automatic Pointer.
    // Converts JSON to a dataset, just the opposite that in the server.
    TFDJSONInterceptor::JSONObjectToDataSets(LJSONObject, LDataSets.get());
    FDMemTableDepartments->Active = false;
    TFDAdaptedDataSet * LDataSet = TFDJSONDataSetsReader::GetListValue
        (LDataSets.get(), 0);
    FDMemTableDepartments->AppendData(*LDataSet);
    // Appends the DataSet to FDMemTableDepartment table.
}
void __fastcall TForm2::Button1Click(TObject *Sender)
{
    GetDepartmentNames(); //Calling this method populates the TListView.
}

GetDepartmentEmployees

Cette méthode est utilisée pour télécharger les informations détaillées relatives au département et aux employés pour un département sélectionné. Le code est exécuté lorsque vous cliquez sur les noms de département du TListView.

Placez les constantes dans l'interface ou la section implementation, mais la lecture et la compréhension du code seraient plus faciles si les constantes étaient plus proches du code.

const
  sEmployees = 'Employees';
  sDepartment = 'Department';
private
    { Private declarations }
    procedure GetDepartmentEmployees(const ADEPTNO: string);
procedure TForm2.GetDepartmentEmployees(const ADEPTNO: string);
var
    LDataSetList: TFDJSONDataSets;
    LDataSet: TFDDataSet;
begin
    LDataSetList := ClientModule1.ServerMethods1Client.GetDepartmentEmployees(ADEPTNO);
    // Get department dataset
    LDataSet := TFDJSONDataSetsReader.GetListValueByName(LDataSetList,sDepartment);
    // Update UI
    FDMemTableDepartment.Active := False;
    FDMemTableDepartment.AppendData(LDataSet);

    // Get employees dataset
    LDataSet := TFDJSONDataSetsReader.GetListValueByName(LDataSetList, sEmployees);
    // Update UI
    FDMemTableEmployee.Active  := False;
    FDMemTableEmployee.AppendData(LDataSet);
end;

Implémentez l'événement OnChange du TListView pour appeler la procédure GetDepartmentEmployees.

procedure TForm2.ListViewDepartmentsChange(Sender: TObject);
var
  LDEPTNO: string;
begin
  // Show department/employee details
  LDEPTNO := TListViewItem(ListViewDepartments.Selected).Detail;
  GetDepartmentEmployees(LDEPTNO);
end;
  • Dans C++ :

Placez la déclaration des constantes dans le fichier ClientUnit.cpp. Vous pouvez ajouter les constantes dans l'interface ou la section implementation, mais la lecture et la compréhension du code seraient plus faciles si les constantes étaient plus proches du code.

const System::String sEmployees = "Employees";
const System::String sDepartment = "Department";

La déclaration de la méthode se trouve dans le fichier ClientUnit.h.

public:     // User declarations
    void GetDepartmentEmployees(const System::String ADEPTNO);

Ce code se trouve dans le fichier ClientUnit.cpp.

void TForm2::GetDepartmentEmployees(const System::String ADEPTNO) {
    TJSONObject* LJSONObject
        (ClientModule1->ServerMethods1Client->GetDepartmentEmployees(ADEPTNO));
    std::auto_ptr<TFDJSONDataSets>LDataSets(new TFDJSONDataSets());
    TFDJSONInterceptor::JSONObjectToDataSets(LJSONObject, LDataSets.get());

    { // multiple declaration for 'LDataSet'
        TFDAdaptedDataSet * LDataSet = TFDJSONDataSetsReader::GetListValueByName
            (LDataSets.get(), sDepartment);
        // Update UI
        FDMemTableDepartment->Active = False;
        FDMemTableDepartment->AppendData(*LDataSet);
    }

    { // multiple declaration for 'LDataSet'
        TFDAdaptedDataSet * LDataSet = TFDJSONDataSetsReader::GetListValueByName
            (LDataSets.get(), sEmployees);
        // Update UI
        FDMemTableEmployee->Active = False;
        FDMemTableEmployee->AppendData(*LDataSet);
    }
}

Implémentez l'événement OnChange du TListView pour appeler la procédure GetDepartmentEmployees.

void __fastcall TForm2::ListViewDepartmentsChange(TObject *Sender)
{
    // Show department/employee details
    System::String LDEPTNO = ((TListViewItem*)(ListViewDepartments->Selected))->Detail;
    GetDepartmentEmployees(LDEPTNO);

}

Procédure ApplyUpdates

Les données stockées dans "FDMemTableDepartment" et "FDMemTableEmployee" peuvent être modifiées par le biais de l'interface utilisateur. Lorsque l'utilisateur clique sur le bouton "Appliquer les mises à jour", le code suivant est utilisé pour renvoyer les mises à jour au serveur.

  • Dans Delphi :

Vous devez d'abord créer une fonction pour obtenir le TFDJSONDeltas :

private
    { Private declarations }
    function GetDeltas: TFDJSONDeltas;
function TForm2.GetDeltas: TFDJSONDeltas;
begin
  // Post if editing
  if FDMemTableDepartment.State in dsEditModes then
  begin
    FDMemTableDepartment.Post;
  end;

  if FDMemTableEmployee.State in dsEditModes then
  begin
    FDMemTableEmployee.Post;
  end;

  // Create a delta list
  Result := TFDJSONDeltas.Create;
  // Add deltas
  TFDJSONDeltasWriter.ListAdd(Result, sEmployees, FDMemTableEmployee);
  TFDJSONDeltasWriter.ListAdd(Result, sDepartment, FDMemTableDepartment);
end;

Créez maintenant la méthode pour appliquer les modifications :

private
    { Private declarations }
    procedure ApplyUpdates;
procedure TForm2.ApplyUpdates;
var
  LDeltaList: TFDJSONDeltas;
begin
  LDeltaList := GetDeltas;

  // Call server method.  Pass the delta list.
  ClientModule1.ServerMethods1Client.ApplyChangesDepartmentEmployees(LDeltaList);

end;

Implémentez l'événement OnClick pour appeler la procédure ApplyUpdates.

procedure TForm2.ButtonApplyUpdatesClick(Sender: TObject);
begin
  ApplyUpdates;
end;
  • Dans C++ :

La déclaration de la méthode se trouve dans le fichier ClientUnit.h.

public:     // User declarations
    void ApplyUpdates();

Ce code se trouve dans le fichier ClientUnit.cpp.

void TForm2::ApplyUpdates() {
    // Post if editing
    if (dsEditModes.Contains(FDMemTableDepartment->State)) {
        FDMemTableDepartment->Post();
    }

    if (dsEditModes.Contains(FDMemTableEmployee->State)) {
        FDMemTableEmployee->Post();
    }

    // Create a delta list
    TFDJSONDeltas * LDeltas = new TFDJSONDeltas();
    // Add deltas
    TFDJSONDeltasWriter::ListAdd(LDeltas, sEmployees, FDMemTableEmployee);
    TFDJSONDeltasWriter::ListAdd(LDeltas, sDepartment, FDMemTableDepartment);

    TJSONObject * LJSONObject(new TJSONObject());
    TFDJSONInterceptor::DataSetsToJSONObject(LDeltas, LJSONObject);

    // Call server method.  Pass the delta list.
    ClientModule1->ServerMethods1Client->ApplyChangesDepartmentEmployees
        (LJSONObject);

}

Implémentez l'événement OnClick pour appeler la procédure ApplyUpdates.

void __fastcall TForm2::Button2Click(TObject *Sender)
{
    ApplyUpdates();
}

Voir aussi