Page 1 of 3 1 2 3 LastLast
Results 1 to 15 of 40

Thread: Gebruik van Onvalidate

  1. #1
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747

    Gebruik van Onvalidate

    In het kader van 'Gescheiden Programmeren' is het dus een must om je data te valideren buiten de GUI-Form om. Zelfs beter om dat in je datamodule te doen.

    Maar hoe ga ik aan mijn GUI-Form vertellen dat er iets fout is gegaan tijden een controle? De datamodule heeft (mag geen) dialogs.pas bevatten, omdat deze voor data is en niet voor andere doeleinde.

  2. #2
    Reader
    Join Date
    May 2002
    Location
    Holland
    Posts
    3,382
    Code:
    if not OK then
      raise exception.Create(...)
    of handiger:
    Code:
    if not OK then
      raise MyValidationException.Create(...)
    <edit> En in je form of app kun je dan deze excepties afvangen (of niet)
    Last edited by Anoniem; 16-Jan-13 at 13:47. Reason: toevoeging

  3. #3
    Jep. In het algemeen werken exceptions goed voor dat doel. Volgens mij kun je ze ook in het OnBeforePost event afvuren. Het posten wordt dan afgebroken, de exception propageert door naar de code die de post aanriep (en naar de code die die code aanriep), zodat je het in je GUI kunt afvangen. Of gewoon niet, zodat je applicatie het op het hoogste niveau doet.

    Als je een transactie hebt die goed in elkaar zit, dan zal die ook netjes afgebroken worden. Doorgaans ziet dat er ongeveer zo uit:

    Delphi Code:
    1. StartTransactie;
    2. try
    3.   // Post data a
    4.   // Post data b
    5.   // Post data c
    6.   // Post data d
    7.   Commit;
    8. except
    9.   Rollback;
    10.   raise;
    11. end;
    Op deze manier heb je altijd een commit als alles goed gaat. Als één van de posts een fout geeft, wordt rollback aangeroepen en wordt de exception vervolgens ongewijzigd doorgestuurd.

    Of loop ik nou op de vragen vooruit?
    1+1=b

  4. #4
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    Quote Originally Posted by Goleztrol
    Of loop ik nou op de vragen vooruit?
    Ja

    Was een inkoppertje, Eric

    Maar als ik dan de DBedit een kleurtje wilt geven, omdat de invoer fout is, moet ik toch wat in de GUI kunnen uitvoeren. Zoals in dit voorbeeld:

    datamodule:
    Delphi Code:
    1. type   TOnChangeEditColor = procedure(Sender: TObject; const Value: boolean)  of object;
    2.  
    3.   private
    4.     { Private declarations }
    5.     FOnChangeEditColor : TOnChangeEditColor;
    6.   public
    7.     { Public declarations }
    8.     property OnChangeEditColor: TOnChangeEditColor
    9.              read FOnChangeEditColor write FOnChangeEditColor;
    10.  
    11.  
    12. procedure TDM.DoMyFieldValidate(Sender : TField);
    13. var Gevonden : boolean;
    14. begin
    15.   Gevonden := Sender.IsNull;
    16.   if Assigned(FOnChangeEditColor) then
    17.    FOnChangeEditColor(Self, Gevonden);
    18. end;

    Form:
    delphi Code:
    1. private
    2.     procedure DoChangeEditColor(Sender: TObject; const Value: boolean);
    3.  
    4. procedure TForm.FormCreate(Sender: TObject);
    5. begin
    6.   DMArt.OnFillMyDBCheckListBox := DoChangeEditColor;
    7. end;
    8.  
    9. procedure TForm.DoChangeEditColor(Sender: TObject; const value : boolean);
    10. begin
    11.   if value then (sender as TDBedit).color := clRed else (sender as TDBedit).color := clWindow;
    12. end;

  5. #5
    Reader
    Join Date
    May 2002
    Location
    Holland
    Posts
    3,382
    Ah nee, dat zou ik niet zo doen.
    Ik zou een FieldException maken en die opvangen,
    Of een OnError(Field) event in de Datamodule.
    De GUI moet dan maar bepalen wie of wat er gekoppeld is aan dat veld.

    Er is ook nog een FocusControl - geloof ik - van TField, maar dat vind ik een vrij zieke implementatie.

  6. #6
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    Met andere woorden: een melding geven mag (of een oplossing bieden), maar aan de GUI mag niets veranderen, omdat het in strijd is met GUI-data scheiding.

    Dan ben ik wel benieuwd hoe andere vertellen dat er iets mis is met de invoer d.m.v. een verandering op de GUI-form.

  7. #7
    Jan
    Join Date
    Oct 2007
    Location
    Mijdrecht
    Posts
    906
    Ik doe data validaties gewoon in de GUI, tenzij daar database gegevens bij betrokken zijn. Onzin om alles naar de achterkant te verplaatsen.

  8. #8
    Reader
    Join Date
    May 2002
    Location
    Holland
    Posts
    3,382
    Een klein delphi 7 abstract voorbeeldje van hoe ik het ongeveer zou doen.
    TData simuleert een datamodule.
    Attached Files Attached Files

  9. #9
    TDigitalTrain user Hans Brenkman's Avatar
    Join Date
    Mar 2002
    Location
    Weert
    Posts
    1,861
    @Eric, dit is wel een heel erg abstract voorbeeldje, een lege unit en een leeg form die niets met elkaar van doen hebben
    Testen kan niet de afwezigheid van fouten aantonen, slechts de aanwezigheid van gevonden fouten.

    Het is verdacht als een nieuw ontwikkeld programma direct lijkt te werken: waarschijnlijk neutraliseren twee ontwerpfouten elkaar.

  10. #10
    Silly member NGLN's Avatar
    Join Date
    Aug 2004
    Location
    Werkendam
    Posts
    5,133
    John, ik zou ook een event maken. Op één of andere manier vind ik dat prettiger dan exceptions afvangen, maar het kan ook zomaar zijn dat ook ik alle voordelen van exceptions raisen nog niet helder heb.

    Enfin, stel je doet zoiets met een event, dan zou ik het welliswaar toch iets anders doen. Om jouw idee even na te lopen: je noemt je event in de datamodule OnChangeEditColor. Er vanuit gaande dat je data en GUI wilt scheiden, en de datamodule in theorie dus niets van een GUI afweet, is dat dus een verkeerde benaming en ook een verkeerde keuze: de data module weet helemaal niet dat er een waarde met een Edit veld bewerkt/ingevoerd wordt. En helemaal al niet dat jouw GUI kleuren weer kan geven: misschien is de GUI wel een head-up display, of een zwartwit-scherm, of een telraam, of...

    Hoe ik het zou doen in geval van events:

    Delphi Code:
    1. type
    2.   TOnValidateError = procedure(Sender: TDataModule; Field: TField; const Message: String) of object;
    3.  
    4.   TMyDataModule = class(TDataModule)
    5.   private
    6.     FOnValidateError: TOnValidateError;
    7.   protected
    8.     procedure ValidateError(Field: TField; const Message: String);
    9.   public
    10.     property OnValidateError: TOnValidateError read FOnValidateError write FOnValidateError;
    11.   end;
    Treedt er een fout op ergens in de validatie van een veld, dan roep je ValidateError aan. Het form implementeert hiervoor een handler, en kan zelf a.d.h.v. het veld en de message beslissen hoe de error wordt gepresenteerd aan de gebruiker. Message kan natuurlijk ook een identifier zijn. Bovendien ga ik er hier vanuit dat een geslaagde validatie niét wordt doorgegeven aan het form, maar dat is een keuze.
    (Sender as TNLDUser).Signature := 'Groeten van Albert';

  11. #11
    Reader
    Join Date
    May 2002
    Location
    Holland
    Posts
    3,382
    @Hans: Ben ik iets vergeten? Form met edits en knopje.
    Het form maakt zijn "datamodule" aan.

  12. #12
    TDigitalTrain user Hans Brenkman's Avatar
    Join Date
    Mar 2002
    Location
    Weert
    Posts
    1,861
    Dat zal haast wel, want zo zul je het niet bedoeld hebben :

    form:
    Code:
    unit FMain;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs;
    
    type
      TForm1 = class(TForm)
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.dfm}
    
    end.
    "Datamodule":

    Code:
    unit UData;
    
    interface
    
    implementation
    
    end.
    Misschien een zip gemaakt terwijl je de laatste wijzigingen nog niet opgeslagen had ?
    Testen kan niet de afwezigheid van fouten aantonen, slechts de aanwezigheid van gevonden fouten.

    Het is verdacht als een nieuw ontwikkeld programma direct lijkt te werken: waarschijnlijk neutraliseren twee ontwerpfouten elkaar.

  13. #13
    Reader
    Join Date
    May 2002
    Location
    Holland
    Posts
    3,382
    Haha dat is inderdaad wel erg leeg
    Zal vanavond nog een uploaden

  14. #14
    Delphi & OO in Vlaanderen SamWitse's Avatar
    Join Date
    Sep 2007
    Location
    Brussel
    Posts
    833
    Ik ben ook voorstander van de Albert NGLN methode: een event geeft je informatie terug die je GUI kan omvormen in naar kleuren, boodschappen, dialogs, shutdown of wat dan ook.
    Events kun je maken in allerlei eigen Eventtypes; om zo de juiste informatie terug te geven, en niet enkel een string.

    Ik heb zelfs een dataset die een event triggert met een warning als een ingevoerd jaar te ver in het verleden ligt. Aan de GUI (of in dit geval het controller-gedeelte van de applicatie) te oordelen of een warning van een oude datum zinvol is of niet, en dit aan de dataset als antwoord in het event terug te geven.
    Should array indices start at 0 or 1? My compromise of 0.5 was rejected without, I thought, proper consideration.

    Sam Witse.
    Delphi & OO in Vlaanderen

  15. #15
    Quote Originally Posted by SamWitse View Post
    Events kun je maken in allerlei eigen Eventtypes; om zo de juiste informatie terug te geven, en niet enkel een string.
    Exceptions ook.

    Ik gebruik het OnValidate event eigenlijk haast nooit, maar in het algemeen gebruik ik liever exceptions bij databaseinteracties. Je krijgt namelijk al een hoop exceptions om je oren.

    Als je een jaartal in wilt voeren, en je voert 3 letters in, dan krijg je toch al een exception. Waarom zou ik dan een event gaan geven als het wel cijfers zijn, maar de verkeerde? Ik heb de exception handling toch al liggen, dus voor mij is er weinig verschil tussen: "Je invoer is poep: dit past niet in het veld" en "Ok, het is een getal, maar geboortedatum mag niet in de volgende eeuw liggen".

    De feedback voor 'bijna buiten bereik' zie ik ook niet helemaal. Ik denk dat het aan je GUI is om aan de databaselaag te vragen wat de exacte grenzen zijn, en zelf te bepalen (al dan niet op basis van organisatiebrede instellingen) wanneer een waarschuwing op z'n plaats is.
    1+1=b

Page 1 of 3 1 2 3 LastLast

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •