1
Manuale Servoy per Principianti
di
Servoy Training & Consulting
San Francisco, CA, USA
Website: www.mcgilly.com
E-mail:
[email protected]
v 1.1 Copyright 2006, All Rights Reserved
Questo manuale viene fornito gratuitamente. Se esso vi risultasse di aiuto
nell’apprendimento di Servoy e voleste contribuire per i costi sostenuti, prego
spedire il vostro contributo tramite PayPal a [email protected].
Gli aggiornamenti saranno effettuati regolarmente – controllate spesso!
Table of Contents
Introduzione .................................................................................................................
Come Imparare Servoy ..............................................................................................
Risorse Disponibili ....................................................................................................
Suggerimento sul percorso da imparare ...................................................................
Ottenere informazioni dal Forum di Servoy ............................................................
Devo conoscere l’ SQL per usare Servoy? ..............................................................
La Architettura di Servoy ............................................................................................
Connessione al database SQL Anywhere ................................................................
SQL Anywhere ........................................................................................................ 15
Connessione al Repository ..................................................................................... 15
Problemi sulla Connessione a SQL Anywhere: ............................................... 17
Creazione e Connessione a un Nuovo Database ................................................... 19
Come posso guardare i dati ?......................................................................................
2
Dove sono memorizzati i miei schemi di database? In Servoy o DBMS? .............
Tabelle e Colonne ........................................................................................................
Sequenze ......................................................................................................................
Tutto ciò che Volete Conoscere sui Foundsets ..........................................................
Che cos’è un foundset? .......................................................................................
Come funzionano i foundsets? ............................................................................
Come programmare la navigazione in un foundset ...................................................
Funzioni Foundset e Funzioni Controller ................................................................
Looping Attraverso un Grande Foundset ...................................................................
Come Aggiunte Modifiche & Cancellazioni influenzano i Foundsets ...............
Contenitori: Vista di Variabili, Dataproviders, Calcoli e Elementi ......................
Dataproviders...............................................................................................................
Come si assegnano i dataproviders nelle form & metodi .........................................
Assegnare un Dataproviders a i Records Correlati ....................................................
Elementi .......................................................................................................................
Molti Controllers Meno Tempo ..................................................................................
Oggetto Controller .......................................................................................................
Oggetto currentcontroller ............................................................................................
Controller Form ...........................................................................................................
Come & Quando il Salvataggio ai Dati Modificati ..................................................
Panoramica sui Salvataggi in Servoy .........................................................................
Uso del setFocusLostSaveEnabled(false) ...............................................................
Uso di Transactions ....................................................................................................
Cambiamenti in Servoy 3.x .......................................................................................
Convalida del Record Prima di Salvare ....................................................................
Panoramica sulla Convalida Dati ...............................................................................
Tre differenti approcci ................................................................................................
Funzione setFocusLostSaveEnabled() .......................................................................
Comportamento di Modifiche e Salvataggio Prima del 3.x .....................................
Verifica Univocità di un Record..................................................................................
Approccio #1 – scrivere generica funzione checkUniqueness() con SQL ..........
Approccio #2 – uso di una relazione per test di uniqueness ................................
Approccio #3 – uso di foundset separato per ricercare matching record ...........
Come Trovare le Date ................................................................................................
Panoramica sulle Date in Servoy................................................................................
La ricerca delle date per gli utenti..............................................................................
Programmare la ricerca delle date in un metodo .......................................................
3
Date con la componente tempo ..................................................................................
Consiglio: Uso di campi DATE invece di campi DATETI ME................................
Spiegazione dei Tabpanels ..........................................................................................
Panoramica sui Tabpanels ..........................................................................................
Related Tabpanels .......................................................................................................
Relationless Tabpanels ................................................................................................
Tabless Tabpanels .......................................................................................................
Come si Programmano i Tabs ....................................................................................
Aggiunta/cancellazione di form a/da un tabpanel esistente ......................................
Le Relazioni ...................................................................................................................
Panoramica sulle Relazioni .......................................................................................
Chiavi Primarie & Chiavi Esterne ............................................................................
Origine & Destinazione: Un Modo di Pensare alle Relazioni in Servoy ............
Relazioni Uno-a-Molti ................................................................................................
Relazioni Molti-a-Uno ................................................................................................
Relazioni Molti-a-Molti ..............................................................................................
Relazioni nominate da voi ..........................................................................................
Relazioni Globali.........................................................................................................
Relazioni Nidificate ....................................................................................................
Lettura, aggiunta & cancellazione di record correlati ...............................................
Riassumendo le Relazioni ...........................................................................................
Opzioni di Relazione ...................................................................................................
Consigli e Convenzioni sulla Programmazione ........................................................
Stabilire convenzioni sui nomi e attenersi ad esse ....................................................
Cliccare non scrivere! ................................................................................................
Usare application.output() per vedere 'ciò che sta girando' ......................................
Dichiarazione di vars globali nella finestra dataproviders ....................................
Usare Ctrl-spacebar per velocizzare la codifica .....................................................
Essere consapevoli del case-sensitivity ................................................................
Settaggio delle proprietà a tempo di esecuzione .......................................................
Usare calcoli non -memorizzati per checkboxes ........................................................
Contenitori che non persistono alla uscita da modalità run -time ......................
Fare spesso il Back up delle soluzioni ...................................................................
Uso dell’help ..............................................................................................................
Global find & replace per correggere dopo la rinomina di un oggetto ................
Tasti chiave per andare in Servoy Editor ................................................................
4
Non dimenticare il doppio == nel comando if! ......................................................
Selezionare righe di codice & formattarle tutte in un colpo ................................
In Editor non usare alcune keywords nei commenti (es.“function”) ...................
I Colori a volte sono strani ........................................................................................
Debugger Consigli e Suggerimenti .............................................................................
Appendice .......................................................................................................................
Creazione di unaTabella con 500 record ...................................................................
Introduzione
Servoy è un brillante ambiente di sviluppo che incrementa la
produttività dello sviluppatore. Riunisce diversi e potenti standard
tecnologici (Java, JavaScript, JDBC, RMI, Database SQL, browser,
CSS, XML ecc.) così da rendere più elegante ed efficiente l’intero
prodotto. Lo Sviluppatore con il prodotto Servoy viene arricchito
delle sue prerogative.
Il mio nome è Adrian McGilly e sono un consulente e istruttore di
Servoy, e membro della Servoy Alliance Network (SAN). Ho una
laurea in Scienza della Informatica e Matematica e ho imparato
Servoy nel 2006 dopo una dec ina di applicazioni sviluppate, usando
principalmente Omnis e i database SQL. Fornisco sviluppo di
applicazioni in Servoy e training a ciascun cliente. Per informazioni
circa corsi di addestramento imminenti e altri servizi per favore fare
riferimento al mio website. I miei corsi di addestramento sono
elencati anche sotto gli Eventi Servoy Website.
Per l’esperienza che maturata, insegno l’ambiente Servoy ai nuovi
sviluppatori e leggendo le domande che vengono poste
quotidianamente sul Forum di Servoy, mi sono accorto che c'erano
dei temi che la documentazione di Servoy esistente non spiegava in
5
modo esaustivo, e ho deciso di fare qualche cosa in merito. Questo
manuale è una raccolta dei ‘come-si fà’ con lezioni e discussioni
per gli sviluppatori che intendono imparare Servoy. Esso non
sostituisce la documentazione Servoy ma la completa, è un aiuto in
modo da ottenere una comprensione più rapida .
Potete spedirmi email per qualsiasi argomento all’indirizzo
[email protected] con domande, commenti, critic he o
correzioni che riguardino qualsiasi aspetto del manuale.
Tutto il contenuto menzionato in questo manuale risulta applicato a
Servoy v. 2.2.5.
I miei ringraziamenti vanno a John Allen, Marc Norman, Jan
Aleman e Bob Cusick per tutti i contributi di idee, correzioni,
incoraggiamenti offerti per la creazione di questo manuale. Un
grande grazie a tutti gli utenti Servoy che con domande e risposte
sul Forum di Servoy mi hanno aiutato a identificare i temi da
includere in questo manuale.
by Adrian McGilly , Servoy Consultant & Trainer
Copyright 2006, All Rights Reserved [TOP]
6
Come Imparare Servoy
by Adrian McGilly
Risorse Disponibili
Ci sono molte risorse disponibili per conoscere e usare Servoy. Di
seguito un elenco di tutto ciò che serve per questo:
• Documentazione di Servoy, disponibile per downl oad gratis
formato PDF da PDF Documentation page del sito web di
Servoy o per acquisto in formato libro dal Servoy Store.
Comprende:
Servoy Developer User's Guide
Servoy Developer Reference Guide
Advanced Programming Guide for Filemaker
Developers
Servoy Server Administrator's Guide
• Servoy Magazine, un periodico online conversazionale pieno
di molti consigli, tecniche e come -fare.
• Online Tutorials sul sito web Servoy
•
Servoy Gallery – una sezione del sito web di Servoy che
mostra schermate e spiegazioni su una dozzina le soluzioni
Servoy già in produzione. Guardare a queste schermate è un
modo valido per vedere le complete capacità GUI di Servoy.
• Demo solutions soluzioni demo che potete scaricare dal
website di Servoy, da esplorare e usare come maschere di
esempio per le vostre soluzioni.
• Questo manuale (Servoy Beginner's Handbook di Adrian
McGilly).
[TOP]
7
• The Servoy Forum – un gruppo di discussione online dove
circa 1000 sviluppatori fanno domande, condividono e
ottengono risposte. Il Personale degli sviluppatori di Servo y
rispondono regolarmente alle domande su questo forum.
• E per finire il più importante tool di apprendimento di tutti:
Servoy stesso. Giocate. Pasticciate. Non dovete
preoccuparvi–non vi morde. Il migliore modo per imparare è
fare esperienza.
Suggerimento sul percorso da imparare
Questo è il mio suggerimento del percorso per conoscere Servoy.
1. Caricare l’ambiente Servoy e lanciarlo sul proprio computer
usando il Sybase SQL Anywhere come database. Se avete
problemi di connessione al database Sybase SQL Anywhere
leggere la sezione sulla connessione al database.
2. Leggere la Developer User's Guide . È BENE saltare le parti
che non si sentono molto attinent i alle proprie particolari
necessità ma per voi sarebbe utile spendere del tempo per
ogni sezione di questo libro in modo da capire le complete
capacità di Servoy. Dovrete anche stare molto tempo sulle
cose più difficili in Servoy.
3. Leggete la Developer Reference Guide , ma non cercate di
capire tutto subito. Capirete col tempo.
4. Aprite la soluzione Demo svyCRM che è fornita insieme alla
installazione Servoy e disponibile anche col download dalle
Download Demo Solutions in Servoy Website. Guardate la
soluzione, sia in esecuzione che in modalità di design.
Guardate a come le form funzionano insieme. Guardate ai
metodi presenti. Esplorate la finestra del dataproviders. Non
dovete preoccuparvi di rovinare la soluzione demo – potrete
in ogni momento reinstallarla .
8
5. Se non conoscete JavaScript, guardate il capitolo JavaScript
Primer in Servoy Advanced Programming Guide for
FileMaker Developers . Non avete bisogno di conoscere
molto di JavaScript per cominciare in Servoy, bastano poche
basi elementari - (grammatica, sintassi, dichiarazione di
variabili & controllo del flusso).
6. Se non conoscete l’ SQL, date un’occhiata a SQL primer in
Servoy Advanced Programming Guide for FileMaker
Developers. Secondo la complessità del vostro progetto,
potete anche non avere bisogno di usare SQL, ma è una
buona cosa avere una comprensione di base e di come viene
usato.
7. Evidentemente, se siete Sviluppatori di FileMaker, troverete
che altre parti del Servoy Advanced Programming Guide for
FileMaker Developers sono molto utili.
8. Probabilmente avete in mente un progetto che volete
produrre con l’ausilio di Servoy. Dovete pensare di
suddividerlo in parti semplici - per esempio, una form per
poter registrare e scorrere i records del Cliente , e cominciate
a costruirlo. Quando andrete a sbattere contro certi ostacoli,
la speranza è quella di trovare risposta in questo manuale a
molte delle vostre domande. Altrimenti, cercate in Servoy
Magazine per vedere se qualche articolo è stato scritto sul
tema, poi controllare anche il Forum di Servoy. La prossima
sezione spiega come ottenere risposte dal Forum.
9. Per lo stesso motivo ricordate di dar e uno sguardo a Servoy
Server Administrator's Guide. Potete capire Servoy se ne
capite le capacità di a mministrazione di sistema.
Ottenere informazioni dal Forum Servoy
Probabilmente ogni domanda che un nuovo arrivato avesse quando
comincia con Servoy la trova già nelle risposte sul Servoy Forum. Il
trucco sta nel trovare il percorso che contiene domanda e risposta.
9
Otterrete ulteriore successo se trovate la risposta adatta per voi.
Prendetevi un pò di tempo per capire il motore di ricerca del forum,
come evidenziato sotto. La opzione “ricerca per tutti i termini” in
particolare può aiutarVi a restringere la vostra ricerca.
Devo conoscere l’ SQL per usare Servoy?
La risposta è ‘sì e no’. È utile sapere un poco di SQL, ma in molti
casi non è necessario, e certamente non quando siete principianti.
Servoy vi permette di interrogare il vostro db con l’ SQL invece di
usare i comandi standard find()/search(). Si può passare una query
SQL a una funzione con databaseManager.getDataSetByQuery()
per recuperare righe (records) di un dataset. Quindi potete scorrerne
i dati, stamparne i reports, caricare questi dati in un foundset e
mostrarli su una form, esattamente come se aveste fatto una ricerca
10
con Find() /search(). Questa è una scelta conveniente per quelli che
conoscono le query SQL, ma spesso potete ottenere le stesse cose
anche senza.
Ci sono cose che si possono fare in una query SQL e che invece
non si possono fare usando i comandi find()/search(). Un esempio
sono gli outer joins, usati per reporting (visualizzazioni e stampe) di
tabelle correlate fra loro quando di ogni tabella possono essere
omessi alcuni suoi records. L’SQL può anche essere utile per
recuperare i risultati dal vostro db senza perdere il foundset, come
dimostrato nella sezione verifica della univocità di un record prima
di salvarlo. Con database complessi, consultare direttamente il
database con l’SQL spesso migliorerà significativamente l e
performance delle nostre queries.
Potete anche usare il plugin del rawSQL per modificare i dati del
vostro database coi comandi SQL update, insert e delete, ma
solamente per utenti di Servoy competenti che li conoscono.
Raramente è necessario fare questo.
by Adrian McGilly , Servoy Consultant & Trainer
Copyright 2006, All Rights Reserved [TOP]
11
12
La Architettura di Servoy
by Adrian McGilly
È importante capire l'architettura di Servoy. Segue una vista
(fornitami da Servoy)
Le applicazioni scritte con Servoy sono chiamate soluzioni.
La prima cosa da capire è che la vostra soluzione e i v ostri dati sono
due cose separate (come lo debbono essere!). I dati risiedono in un
(o più) database SQL gestito da un (o più) server di database.
La vostra soluzione risiede in un database SQL chiam ato
[TOP]
13
Repository. Uno dei grandi meriti di Servoy è quello di gestire la
memorizzazione della intera soluzione compreso le vostre GUI e
tutta la codifica, in un database SQL standard, con JDBC conforme.
Quando viene startato Servoy Developer, per default si aspetta di
trovare un database server chiamato repository_server, e il relativo
database chiamato servoy_repository. Qui è dove vengono
immagazzinate le vostre soluzioni.
Quando costruite una soluzione e fate modifiche ai disegni delle
form e agli script (i metodi) che li sotten dono, Servoy in quel
momento sta salvando il disegno della vostra form nel database
servoy_repository. Quando lanciate una soluzione e aprite una
nuova form, Servoy legge la form e tutti i metodi (legati alla form
stessa) e tutti gli attributi direttamente dal servoy_repository. Al
momento di popolare la form con i dati, Servoy legge i dati da
qualsiasi database (o dai database) aziendale . I dati aziendali gestiti
in una soluzione possono risiedere in più database e di più fornitori
diversi. Mentre il repository è sempre contenuto in uno stesso
database.
La parte di Servoy con la quale gli utenti interagiscono direttamente
è il Servoy Client, una applicazione Java che gira sul Java Virtual
Machine disponibile gratis da Sun.
La parte che gestisce tutto l’insieme è il Servoy Server che è scritto
in Java e gira sul Tomcat application server. La applicazione server
risiede tra le postazioni client di Servoy e i database(s), gestisce una
varietà e un numero stupefacente di richieste dai Client di Servoy, e
tutto mentre legge la intera soluzione e i dati del cliente dai database
SQL.
Il Java Client (a volte chiamato Smart Client-intelligente) è una
applicazione Java che gira su Java Virtual Machine di ogni
postazione client e fornisce agli utenti una “ricca esperienza UI”.
Con la versione 3.x, Servoy presen ta un altro tipo di client - il Web
Client. Con il Web Client gli utenti accedono alle soluzioni Servoy
con un web browser. Il Servoy Server configura le forms usando
14
HTML, JavaScript, AJAX e gli altri protocolli browser standard,
completi di bottoni, campi e liste popolate con dati, ecc. e li serve
sul browser. Per alcune limitazioni tecnologiche dei browser, ci
sono alcune caratteristiche UI che sono disponibili al Smart Client
ma non disponibili al Web Client. Dedic herò una sezione al Web
Client in una futura revisione di qu esto manuale.
In aggiunta a queste componenti dell'architettura, i Java beans e
i Servoy Plugins possono essere usati per estendere la funzionalità
di Servoy. Queste componenti risiedono nelle cartelle sul Servoy
Server (Non sulla postazione cliente) e vengono richiamati ogni
qualvolta la soluzione li richiede.
Le funzionalità di Servoy possono essere ulteriormente estese con
le Elaborazioni Batch . Queste sono Soluzioni Servoy inserite in
cartelle speciali sulla macchina server e la loro esecuzione può
essere schedulata dalla Console Administration di Servoy Server.
Quando usate l’ambiente di Sviluppo Servoy, è come se steste
facendo girare una speciale postazione Client di Servoy su di una
mini-versione di Servoy Server.
In questo manuale viene usato il database Sybase ASA che viene
fornito insieme a Servoy, ma la maggior parte del contenuto riferito
al database si applica a tutti i database con driver JDBC-conforme
di diversi fornitori.
by Adrian McGilly , Servoy Consultant & Trainer
Copyright 2006, All Rights Reserved [TOP]
15
Connessione al database SQL
Anywhere
by Adrian McGilly
SQL Anywhere
SQL Anywhere è solo uno dei molti dbs al quale Servoy può
connettersi, ma è l'unico che è fornito con l’ambiente Servoy, e che
presumiamo di usare in questo manuale.
SQL Anywhere ha diversi nomi. A volte viene chiamato ASA che
sta per Adaptive Server Anywhere, e d è venduto da una filiale di
Sybase chiamato iAnywhere.
Prima di andare troppo avanti, voi dovreste scaricare una copia del
tool di gestione del database, chiamato “SQL Anywhere Developer
Edition” il cui componente principale è chiamato Sybase Central.
Sybase Central vi permette di gestire i vostri schemi di database, (i
tracciati di ogni tabella) con gli attributi di ogni colonna come
NOT NULL, INDEXED and UNIQUE, scorrerne le righe (records)
dei vostri dati, scriverne le query SQL, creare nuovi database, ecc.
Per leggere su SQL Anywhere, visitare questo link:
http://www.ianywhere.com/datasheets/sqla ny_9.html
Per scaricare una copia gratuita di SQL Anywhere, visitare la
pagina Download Sybase Central sul sito web di Servoy oppure
andare a: http://www.ianywhere.com/downloads/ e cliccare su SQL
Anywhere Developer Edition
Connessione al Repository
Per lanciare Servoy occorre essere abilitati alla connessione col
database servoy_repository. Quando si apre Servoy, viene
presentato un elenco di soluzioni nel repository e vi si chiede a
quale volete collegarvi.
[TOP]
16
Quando scegliete una di quelle soluzioni, il sistema cercherà di
connettersi al database repository che le contiene tutte, e se non
può trovarlo, voi otterrete un errore.
Ci sono alcuni dettagli da precisare affinchè Servoy si possa
connettere con successo al database Anywhere . Generalmente,
dopo avere installato Servoy voi dovreste connettervi senza
problemi, ma in passato ci sono state installazioni con problemi,
così qui di seguito vengono proposti alcuni consigli in merito .
Quando viene lanciato, Servoy attiva il motore del database SQL
Anywhere che è contenuto principalmente ne l file dbsvr9.exe
(dbsrv9 su Mac) nella cartella Sybase_db. SQL Anywhere guarda
poi nel file sybase.config un elenco di database che si aspetta di
trovare e quindi tenta di aprire ogni database presente nell'elenco.
IMPORTANTE: voi potete vedere se SQL Anywhere è in funzione
quando la sua icona appare nella barra del desktop (su Windows) o
Activity Monitor nella cartella di Applications/Utilities su Mac.
Se SQL Anywhere non parte, Servoy attiverà il seguente
messaggio “non ci si può connettere al repository server specificato
nelle preferenze”. Ogni qualvolta ottenete quest o messaggio, uscite
da Servoy, aprite il file sybase_log.txt nella cartella sybase_db e
andare alla fine. Di solito vedrete a fine file un messaggio che vi
spiega il motivo dell’errore , del tipo “non si può aprire/leggere il
seguente file: database/mydatabase.db.”
Nota: è OK quando nella cartella “database” vengono trovati i
database specificati nel file sybase.config. Non è OK quando nella
cartella “database” non ci sono i database specificati nel file
sybase.
L'altra parte che ha bisogno di essere messa a posto è il settaggio
della connessione a ogni database che Servoy deve usare. Queste
connessioni al database sono chiamate semplicemente “servers”, e
sono elencate nel Menu Modifica>>Preferenze sul tab DB Servers .
Per fare in modo che Servoy si connetta a un database occorre
avere definito un server in questo elenco. Per dettagli sul come si
17
creano questi server database andare al Servoy Developer User’s
Guide.
Prestare attenzione al fatto che se adesempio il vostro database è
crm.db, allora dovete inserire ‘crm’ (senza apici) come nome del
database (non ‘crm.db’).
Problemi sulla connessione a SQL Anywhere:
Corruzione o non sincronizzazione del .log e database
Ciascun database ha un file .log con lo stesso nome (es. il
file log di crm.db è il crm.log). Può accadere che il file di log
non sia più sincronizzato con l'archivio del db. In questo
caso, potete provare a cancellare l'archivio di log e SQL
Anywhere ne creerà uno nuovo alla successiva prima
apertura del database.
Se non funziona, potete costringere Sybase a startare il
database senza un archivio di .log usando la scelta '-f '.
1. In Windows, la procedura è:
2. Chiudere Servoy e chiudere ogni server Sybase.
3. Lanciare la applicazione dbsrv9.exe presente nella
cartella Servoy\sybase_db
4. La applicazione vi permette di specificare i l nome
database .db che dovete aprire, quindi inserite il
carattere -f nel campo delle opzioni
5. Premete OK.
Su Mac, la procedura è:
Aprite una nuova finestra con /Applications/Terminal
e inserire questi comandi (supponiamo che la vostra
directory Servoy è localizzata in
/Applications/Servoy):
18
cd /Applications/Servoy/database
export
DYLD_LIBRARY_PATH=/Applications/Servoy/syba
se_db
export
PATH=$PATH:/Applications/Servoy/sybase_db
dbsrv9 -f servoy_repository.db
Versioni Discordanti di SQL Anywhere
Ho visto accadere un errore riportato nel file sybase_log.txt,
qualcosa come “manca capacità 32 ” o “manca capacità 35”.
Questo di solito ha a che fare con versioni discordanti tra il
database e il motore del database SQL Anywhere . Ciò non
dovrebbe mai accadere con una installazione nuova , ma può
accadere più avanti quando per esempio aprite un db con
Sybase Central usando una versione più recente d el motore
database dbsrv9.exe di quello usato nelle cartelle di Servoy.
Se accade questo, basta portare la applicazione (dbsrv9.exe )
di Sybase in quella presente nella cartella di Servoy e questo
dovrebbe risolvere il disallineamento.
Firewalls
I Firewalls possono interferire con Servoy nella connessione
ai database SQL Anywhere. Se avete problemi di
connessione, allora vi potrà essere di aiuto se potete chiudere
il vostro firewall. Se state usando un firewall, cercate ne lla
vostra configurazione del firewall tutte le regole che
bloccano l’accesso al/dal dbsrv9.exe e rimuovete queste
regole.
Corruzione del Database
Se qualcuno dei dbs elencati in sybase.config si è corrotto vi
19
potrebbe causare problemi. voi potete tentare di correggere
la corruzione del database lanciando l’applicazione
dbsrv9.exe con il parametro –f e a “force” il database.
Aver bisogno di rilanciare SQL Anywhere e Servoy
Se voi cambiate qualcosa in sybase.config, le modifiche
avranno effetto solo la volta successiva che SQL Anywhere
viene lanciato. Se SQL Anywhere sta già girando e voi aprite
Servoy, i vostri cambiamenti a sybase.config saranno
ignorati. Così dopo avere fatto i cambiamenti a questo
archivio, assicuratevi di uscire da SQL Anywhere prima di
lanciare Servoy. Per chiudere SQL Anywhere in Windows,
dovete trovate la relativa icona nella barra in basso , poi click
col tasto destro sull’icona e selezionate exit (o su Mac,
scegliere ‘Quit’ dopo avere selezionato ‘dbsrv9 ' usando
Activity Monitor?.
Egualmente, se pensate di aver predisposto tutto bene ma
Servoy si rifiuta ancora di connettersi, allora dovete sempre
chiudere sia Servoy che SQL Anywhere, e poi rilanciare –
Servoy usa un approccio tipo “caricamento pigro” al suo
lancio e questo significa che alcuni cambiamenti non
avranno effetto finché Servoy non viene rilanciato.
Creazione e Connessione a un Nuovo Database
Quando Servoy si è connesso con successo a SQL Anywhere, voi
vorrete creare una soluzione nuova e iniziare a giocarci. Che
database usereste?
Voi potete usare uno dei database di esempio esistenti che vengono
installati insieme a Servoy (sono inclusi example_data.db,
user_data.db, crm.db e udm.db) oppure potete creare un database
nuovo.
In questo momento non siete ancora in grado di creare un db nuovo
20
in Servoy. Per farlo avete bisogno delle seguenti cose:
1. Uscire da Servoy
2. Chiudere il server SQL Anywhere usato da Servoy. Per
chiudere SQL Anywhere in Windows, potete trovate la sua
icona nella barra sul desktop, fare un click e scegliere exit (o
su Mac, scegliere ‘Quit’ dopo avere selezionato ‘dbsrv9 '
usando l’Activity Monitor?.
3. Aprire Sybase Central e crea re un nuovo db e salvarlo nella
cartella servoy\database. I dettagli su questa operazione si
trovano in Servoy Developer User’s Guide ma la cosa più
importante è di NON connettersi al nuovo db creato finché
non avete completato i passi seguenti.
4. Aggiungete il vostro database nuovo nel file sybase.config
della cartella sybase_db della vostra directory Servoy.
5. Avviare Servoy.
Se Servoy apre con successo SQL Anywhere e si connette al
repository, allora vi verrà presentato un elenco di soluzioni
disponibili. Uscite premendo Annull e andate alle Preferenze
sul tab DB Servers per aggiungere la connessione al vostro
nuovo database. Per default lo username e la password per il
vostro nuovo database SQL Anywhere è:
username=dba
password=sql.
Servoy vi salverà questa nuova connessione, solo se la
connessione al server database avrà successo.
Nell'elenco dei server di database in Preferences>>DB Servers, ci
sarà un X rossa vicino a ogni server sul quale non è riuscita la
connessione al database corrispondente .
21
Come posso guardare i dati?
Potete usare Sybase Central per guardare gli schemi e i dati di ogni
tatabella cliente. Quando vi connettete a un db con Sybase Central
potete andare su ogni tabella dati, selezionate il tab ‘data’ e
visualizzate le righe e le colonne dei vostri dati. Sappiate che se
fate delle modifiche ai dati in ambiente Servoy, per poterli vedere
in Sybase Central dovete fare un refresh oppure chiudere e riaprire .
C'è anche un editor di Query SQL conversazionale in Sybase
Central che vi può essere utile (sebbene non è difficile costruire un
tool simile in Servoy - c'è n’è uno già costruito nella soluzione
demo svyCRM, che si chiama AdHoc Query sotto il tab Admin).
by Adrian McGilly , Servoy Consultant & Trainer
Copyright 2006, All Rights Reserved [TOP]
22
Dove sono memorizzati i miei schemi di
database? In Servoy o in DBMS?
by Adrian McGilly
Tabelle e colonne
Servoy permette di gestire alcune cose sul database all’interno del
suo ambiente. Potete creare e cancellare ta belle di database, creare
colonne, e le sequenze di tabella. Per qualsiasi altro tipo di
modifiche allo schema (es. modificare l’attributo, rinominare o
cancellare una colonna , rinominare una tabella ecc.) avrete
assolutamente bisogno di usare Sybase Central.
Quando una soluzione Servoy viene aperta, carica lo schema del
db. Se voi andate in Sybase Central e modificate lo schema del db
(es. aggiungete una colonna, cambiate gli attributi di una colonna,
aggiungete una nuova tabella) vedrete i cambiamenti nella finestra
del dataprovider di Servoy la volta successiva che avviate Servoy.
(È meglio chiudere SQL Anywhere e rilanciare Servoy dopo avere
fatto le modifiche, sebbene in alcuni casi non sia proprio
necessario.)
Voi dovete prestare attenzione quando fate questo, così come
modificare qualsiasi indice assegnato alle tabelle e alle colonne.
Alcuni esempi:
[TOP]
23
Modifiche al backend DB Effetti in Servoy
Rinominare una colonna
Il nome nuovo apparirà nella
finestra di Dataproviders la volta
successiva che avviate Servoy ma il
campo assegnato a quella colonna
su qualsiasi form sarà mostrato
vuoto–poichè contiene il vecchio
nome–e tutti i metodi che usano
quel vecchio nome causer anno un
errore.
Cancellare una colonna
I cambiamenti appariranno nella
finestra Dataproviders la volta
successiva che avviate Servoy;
qualsiasi campo assegnato alla
colonna cancellata sarà mostrato
vuoto; i metodi che usano quella
colonna causeranno un errore.
Modificare attributi di
colonne
I cambiamenti saranno riflessi nella
finestra Dataproviders alla
successiva apertura di Servoy;
invece il funzionamento dei campi
che mostrano quella colonna e dei
metodi che usano quella colonna
può essere possibile ma ciò dipende
dal tipo di modifiche apportate.
Cancellare o rinominare
una tabella
Se cancellate o rinominate una
tabella che è usata in una soluzione,
otterrete un errore , sia allo startup
della vostra soluzione che anche la
prima volta che la soluzione usa la
tabella.
24
Notare che c'è un comando global find & replace in Servoy Editor che vi permette
di fare cambiamenti globali ai vostri metodi JavaScript. Non ci sono però comandi
find/replace che agiscono sui settaggi nel pannello delle proprietà.
Sequenze
Voi potete definire le sequenze in Servoy. Un inserimento di sequenza, chiamato
“Servoy Sequence” permette a Servoy di gestire la generazione di una sequenza
numerica (diversa dalla “sequenza database” dove si desidera generare una
sequenza numerica sul database server). Nel caso di Sequenze Servoy, le
informazioni vengono memorizzate SU ciascuna sequenza (come “entità da
incrementare” che calcola il successivo numero di sequenza) nel repository, ma i
numeri di sequenza stessi rimangono nel database.
by Adrian McGilly , Servoy Consultant & Trainer
Copyright 2006, All Rights Reserved [TOP]
25
Tutto ciò che Volete Conoscere sui
Foundsets
by Adrian McGilly
Che cos’è un foundset?
Ogni volta che una soluzione Servoy richiede dati dal database,
viene creato un Foundset contenente i risultati da una query. Più
tardi vedremo il dettaglio di come e dove questo viene fatto, ma per
ora pensate solo a l Foundset come a un insieme di records
recuperati dal db, e che la soluzione può ‘usare’. Quando i records
dati sono contenut i in un foundset, Servoy offre molti modi facili
per visualizzarli, ordinarli, editarli, cancellarli, stamparli e
genericamente elaborarli. In altre parole, i Foundsets vi sono amici.
Quando create una form in Servoy, le indicate su quale db essa
deve essere collegata. Questo settaggio è inserito nella proprietà
tableName della form e può essere visto nel pannello delle proprietà
quando vengono visualizzate le proprietà per quella form.
Questo non significa che siete limitati a lavora re solo con le colonne
di quella tabella sulla form, ma serve solo come spunto iniziale.
(Come vedrete, user emo degli altri ingegnosi strumenti Servoy
come le Relazioni e i Tabpanels per acquisire i dati da altre tabelle,
ma lo vedremo più tardi.) Per default (predefinizione), le form che
sono collegate sulla stessa tabella condivideranno anche lo stesso
foundset. Due form collegate alla stessa tabella mostreranno per
default gli stessi records quando vengono aperte, e inoltre lo stesso
esatto record sarà il record “selezionato” o il record “corrente” in
entrambe le form.
In caso di bisogno, sarete contenti di sapere che esiste una proprietà
su ogni form chiamata “Use Separate Foundset’ che, se posta a true,
permette a ciascuna form di avere il proprio foundset. (Notare che
questa caratteristica non funziona quando una form viene
pubblicata nel web client prima del 3.x)
[TOP]
26
È utile sapere che quando la vostra soluzione aggiunge, modifica e
cancella delle righe, queste operazioni riguardano sia il vostro
foundset di lavoro che il db finale. Così se voi siete su una form con
100 records nel suo foundset corrente e aggiungete cinque records a
quella form, il vostro foundset contiene ora 105 records. Se voi
aveste cancellato 5 records invece di averli aggiunti, il vostro
foundset conterrebbe 95 records.
Un modo valido per vedere come i Foundsets si comportano è usare
come esperimento una tabella con almeno 500 records di dati.
Sfortunatamente, i dati di esempio coi quali viene installato Servoy
non contiene molt i records nelle varie tabelle . Voi potete riempire
rapidamente una tabella con Servoy. Basta creare una form,
collegarla al metodo seguente e poi lanciare il metodo stesso:
for (var i = 1; i <=500; i++)
{
controller.newRecord();
// Servoy genererà automaticamente il pks, ma
// voi potete anche riempire il contenuto in
// alcuni campi così da avere alcune colonne
// di dati per giocarci e ri cercare ancora
// es. potete inserire 'Firstname 1', 'Firstname 2',
// ...'Firstname 500' nella colonna chiamata
//first_name.
first_name = 'Firstname ' + i;
}
Se vi servono ulteriori spiega zioni passo x passo per approfondire
questo tema, vedere Creazione di una Tabella con 500 Record in
Appendice.
Quando avete 500 record nella tabella e una form collegata ad essa,
cominciate a giocare con ricerche, inseri menti e salvataggio dei
dati, viste di elenchi, viste di record, viste di tabella, ecc.
27
(illustrato di seguito) così da ottenere lo slider (controllo dei
records) di default (illustrato sotto) per navigare nei records del
foundset. I numeri su questo slider sono abbastanza precisi.
Facciamo un esempio. Diciamo che avete una tabella Companies
con 500 records. Voi create la form customerForm collegata a
quella tabella e poi aprite la form a tempo di runtime (in
esecuzione).
Quando aprite una form in Servoy, per default verrà creato un
foundset che comprende tutti i records della tabella che in questo
caso sono 500, ordinato per chiave primaria. Poniamo l’ipotesi che
facciamo una query che ci ritorna 450 records. Il foundset ora
contiene 450 records, mentre la tabella del db contiene ancora 500
records. Quando la ricerca termina, Servoy carica solamente i primi
200 records del foundset. Questo viene chiamato foundset parziale.
Ora potete selezionare nel vostro form i 200 records del foundset
28
parziale e, quando richiesto Servoy automaticamente re cupera i
successivi 200 così da avere un foundset parziale di 400 a fronte di
un foundset totale di 450 recuperati dalla tabella del database che n e
possiede sempre 500.
Ora potete selezionare i 400 records del foundset parziale e Servoy
quando richiesto, recupererà i rimanenti 50 records e renderà il
foundset parziale uguale al vostro foundset.
Come funzionano i foundsets?
Che cosa avviene realmen te?
Per rispondere a questa domanda abbiamo bisogno di guardare di
nuovo all'architettura di Servoy. Ricordate che in produzione (non
in sviluppo), sono tre i livelli che lavorano in concerto: il server
database, Servoy Server, Servoy Client. ( L’ambiente di sviluppo,
contiene infatti già una istanza locale dell' Application Server) .
Ogni volta che create un foundset in Servoy, voi state creando un
oggetto nella memoria d i App Server che monitorizza un certo
insieme di cose. L’Application Server recupera un elenco di chiavi
primarie (PKs) per tutti i records che si accoppiano nella ricerca, e
mantiene in memoria l'elenco. E mantiene anche traccia di:
• la “query” che ha creato il foundset,
• il numero totale di records presenti nel foundset,
• quali records sono mostrati attualmente, e su quali form
• quali records del foundset sono attualmente selezionati.
• quali records modificat i/cancellati dalla creazione foundset
• in quali forms della soluzione questi records sono mostrati
• quali altre postazioni Servoy clien ts stanno elaborando questi
29
records (es. in un vero contesto di produzione App Server)
• e altre cose di cui ora non dobbiamo preoccuparci.
Così quando fate una ricerca che restituisce 450 records, Servoy
crea un elenco SUL SERVER ( NON nella memoria del client) dei
450 PKs (codici chiave) nel foundset. Servoy fornisce i 200 PKs al
client alla volta, assieme a tutte le colonne dati solo per i records da
mostrare sul form.
Quando navigate nel foundset, il client sa quali archivi devono
essere mostrati e quindi richiede le corrispondenti colonne da app
server usando il PKs fornito dal server. Quando richiedete un
multiplo di 200 records del foundset, il server spedisce al cliente un
altro blocco di 200 PKs.
Tornando al nostro esempio, poniamo che Servoy abbia r ecuperato i
primi 200 records dei vostri 450 -records e voi avete selezionato il
decimo record. Questa è un'illustrazione di ciò che sta facendo:
Come programmare la navigazione in un foundset
Ora noi sappiamo qualcosa sui foundsets, com e vengono creati e
come si implementano. Quali tools sono disponibili al
programmatore per navigare e elaborare i foundsets?
30
Ci sono molte funzioni disponibili per gestire i foundsets. La
maggior parte si trova nell'albero del Servoy Editor, sotto il nodo
controller della form, una coppia di funzioni si trova sotto il nodo
foundset e altri ancora si trovano nella classe del databasemanager.
Per ora, concentriamoci su alcune funzioni chiave che coprono la
maggior parte di ciò di cui si ha bisogno per gove rnare un foundset:
Function
Description
databasemanager.
getFoundSetCount(foundset)
restituisce il numero totale di
records del vostro foundset
(non solo quanto è stato
restituito finora al client, ma
quanti sono in tutto).
Nel nostro esempio, sono
450.
Notare che sebbene la
documentazione Servoy
avverte che questa può essere
un 'operazione costosa ', in
realtà lo è solo se ci sono più
di 100.000 records in tabella
nel qual caso avrete un
leggero rallentamento nella
elaborazione che state
usando.
controller.getMaxRecordIndex()
restituisce il numero di
records del vostro parziale
foundset (es. il numero di
records che sono stati forniti
al client tramite le chiavi
31
PKs). Nel nostro esempio
all’ inizio erano 200, poi
andarono a 400 e alla fine
450.
Potete ottenere lo stesso
risultato con
foundset.getSize().
databasemanager.
getTableCount(foundset)
restituisce il numero di
records della tabella sulla
quale si basa il foundset. Nel
nostro esempio sono 500
controller.getSeletedIndex(n)
Seleziona il numero che
individua il record nel
foundset, nell’esempio è 10
controller.setSelectedIndex(n)
restituisce il record
attualmente selezionato del
foundset (spiegazioni ulteriori
più avanti)
Forse il più importante di questi comandi è l'ultimo,
controller.setSelectedIndex(n) che seleziona l’ennesimo record del
foundset. (Il numero indicato a cominciare dal primo record, così
selSelectedIndex(5) seleziona il quinto record del foundset).
Che vuole dire ‘selezionare le 5 righe del foundset '? Vuole dire due
cose:
• Visivamente, quella riga sarà mostrata e selezionata sulla
form che visualizza il foundset.
• Tutti i valori di ogni colonna di quel record saranno caricati
nel dataproviders di Servoy per quella tabella, quindi tutti
questi valori saranno disponibili ai vostri metodi per leggerli
32
e scriverli.
• Se i records che avete selez ionato sono un multiplo di 200,
verrà lanciata la ricerca dei successivi 200 records
Tornando al nostro esempio, poniamo di aver appena fatto una
ricerca per recuperare i primi 200 record s dei 450 del foundset. Se
voi fate
controller.setSelectedIndex(199)
voi state selezionando il 199 ° record nel foundset, e caricando il suo
contenuto nel dataproviders. Se fate
controller.setSelectedIndex(200)
voi potete non solo selezionare il 200 ° record ma potreste avviare la
ricerca dei successivi 200 records nel foundset parziale . Attenzione
perchè se fate
controller.setSelectedIndex(250)
se in questo caso voi avete solamente 200 records, non accadrebbe
nulla. Altrimenti non potreste selezionare olt re la fine dell'attuale
foundset caricato, per farlo dovete indicare il multiplo preciso di
200 per lanciare la ricerca anche dei successivi 200 records.
Funzioni Foundset e Funzioni Controller
Se guardate il set di funzioni disponibili sotto il nodo del foundset
di una form, e poi guardate al set disponibile sotto il nodo del
controller, osserverete che sono simili: la maggior parte delle
funzioni del foundset esistono anche come funzioni del controller.
Perchè ci sono due volte? Qual’è la differenza?
Le funzioni del foundset fanno le stesse cose di quelle del
controller, solo che le funzioni foundset sono disegnate per lasciarsi
inserire in modalità istantanea (es. senza riguardare la GUI in tempo
reale), mentre le funzioni del controller riguardano la G UI in tempo
reale.
33
Questo in teoria. In pratica, non è così semplice, ma questa
discussione va oltre lo scopo di questo manuale e sarà aggiunta in
un'altra versione del manuale. La distinzione è valida solo se state
elaborando un grande volume di records e volete velocizzare le
modifiche. Può essere anche qualche volta utile per aggiungere/
cancellare/ modificare dei records senza mostrarli all'utente.
Per ora, la mia raccomandazione è di attenersi alle funzioni del
controller eccetto quando se ne avrà un effettivo bisogno.
Looping Attraverso un Grande Foundset
Una domanda che spesso viene fatta è, come posso scorrere TUTTI
i records oltre i soli 200 che Servoy recupera alla volta?
L'approccio più facile è fare uso di
databasemanager.getFoundSetCount() che recupera il numero
totale di records nel foundset. Voi potete catturare quel valore in
una variabile locale e poi potete fare un loop dal valore di 1 al
valore contenuto nella variabile. Questo il codice:
//dichiarazione di una var locale e suo settaggio al numero totale di
//records nel foundset
var max = databasemanager.getFoundSetCount(foundset)
for (var i = 0; i <= max; i++ )
{
controller.setSelectedIndex(i);
// qui fate un qualsiasi vostro lavoro di cui avete bisogno
Da notare che abbiamo saltato il valore max nella variabile locale
ma solo quello:
for (var i = 0; i <= databasemanager.getFoundSetCount(foundset); i++ )
Ma dati gli avvertimenti di Servoy (discussi sopra) circa l’utilizzo di
memoria della funzione getFoundSetCount() sarebbe molto meglio
evitare di richiamarla ad ogni iterazione di questo loop.
34
Vi è un altro modo di fare un loop attraverso tutti i records di un
foundset:
var i = 0 //dichiarazione di una var locale e inizializzata a 0
while ( i <= controller.get MaxRecordIndex() )
{
//prima legge il record con l’indice i poi lo incrementa di 1
controller.setSelectedIndex(i++);
// qui fate le elaborazioni di cui avete bisogno
}
Oppure potete fare così:
for (var i = 0; i <= controller.getMaxRecordIndex(); i++ )
{
controller.setSelectedIndex(i);
// qui fate le elaborazioni di cui avete bisogno
}
In entrambi i casi, quando la variabile "i" raggiunge il valore di 200
o un suo multiplo, la chiamata al setSelectedIndex(i) innescherà la
ricerca di un'altro lotto di records, ( contenenti lo stesso valore che
verrebbe ricevuto dalla funzione getSize() ) in modo tale che il loop
continuerà a girare fino alla fine di TUTTI i records del foundset.
Come le Aggiunte, Modifiche & Cancellazioni
Influenzano i Foundsets
Quando aggiungiamo un nuovo record usiamo
controller.newRecord()
il record viene aggiunto immediatamente al foundset corrente, ma
non è salvato nel db fino a quando viene compiuto un salvataggio.
Potete leggere sul salvataggio dati qui.
Egualmente, le modifiche vengono salvate subito nel foundset, ma
non sono salvate nel db fino a lla esecuzione di un salvataggio.
Le cancellazioni avvengono simultaneamente nel foundset e nel db.
35
Per default, Servoy salva le modifiche a un record nel db all’uscita
dal record, ma potete cambiare tale comportamento in modo che il
salvataggio nel db venga differito fino a una vostra richiesta. Ciò
significa che potete modificare molti records, (di diversi foundsets!)
prima che questi cambiamenti vengano effettivamente salvati nel
db. Il foundset in questo caso è come una specie di area temporanea
in cui fare modifiche ai records in attesa di conferma.
Nota: questo comportamento non deve essere confuso con le
transazioni database, che hanno altri controlli e sono spiegate qui.
Automatismo di Aggiornamento & Distribuzione dei Dati
L' App Server fà anche del caching molto intelligente in mo do da
minimizzare il numero di volte che deve consultare il database, ma
lo fà senza compromettere l’aggiornamento dei dati. Inoltre
controlla che qualsiasi modifica fatta a qualsiasi records nel
foundset venga riflessa su ogni form della soluzione e natur almente
anche su qualsiasi altra form in ogni postazione client di Servoy!
Per esempio, se cambia te un prezzo unitario da $1.00 a $2.00, che
concerne alcuni calcoli di totale su una sub-form in un tabpanel,
Servoy si prende cura di aggiornare automaticamente il subform.
Inoltre, se un altro utente lavora sulla stessa soluzione e la stessa
form che riguarda quel cambio, allora, Servoy Server aggiornerà
automaticamente quella form. Direi bello. (Notare che questo si
applica solo a chi usa Java client. Per chi usa il web client occorre
compiere un refresh del browser per vedere la modifica .)
by Adrian McGilly , Servoy Consultant & Trainer
Copyright 2006, All Rights Reserved [TOP]
36
Contenitori: Vista di Variabili,
Dataproviders, Calcoli e Elementi
by Adrian McGilly
È importante capire e quindi usare i diversi tipi di contenitori che
Servoy offre per immagazzinare e gestire i dati. La documentazione
di Servoy spiega bene come poter creare e usare questi contenitori
che questa sezione vorrebbe ulteriormente approfondire.
Dataproviders
Dataproviders è il nome che Servoy dà a un gruppo di co ntenitori
che includono i seguenti elementi:
• colonne del database
• calcoli memorizzati
• calcoli non memorizzati
• variabili globali (dichiarate nella finestra del Dataproviders,
non nel vostro codice JavaScript, pratica da scoraggiare)
• aggregazioni
Date uno sguardo alle seguenti:
Colonne del Database
Sono tabelle e colonne dei vari databases servers collegat i e
resi visibili alla vostra soluzione. Leggere Dove sono
memorizzati gli Schemi DB? per una comprensione di come
la vostra soluzione viene accoppiata col vostro schema db.
[TOP]
37
Calcoli Memorizzati
Ci sono speciali istanz e di colonne del database dove il loro
valore viene calcolato da Servoy sulla base d i codice
JavaScript scritto da voi in un metodo. Servoy si prende
automaticamente cura di ricalcolar e e memorizzare nella
tabella i nuovi risultati dovuti alle eventuali modifiche , e
gestisce questo per ogni record della tabella.
Osserverete che quando siete nei calcoli dell’editor (illustrato
in seguito), l’albero è più corto di quello principale nell’
Editor di Servoy. A parte i Globals, gli unici dataproviders
mostrati nell'albero sono della tabella sulla quale si sta
definendo il calc. Egualmente essa mostra solo relazioni che
“iniziano” col nome di quella tabella. Per vedere e gestire
qualsiasi altro oggetto occorre andare direttamente su ognuno
di essi, form, controller, oggetti foundset, oggetti
databasemanager e su tutti gli altri oggetti usati in Servoy
Editor. C'è un valido motivo per questo.
Sebbene Servoy non vi limita nella scrittura del codice. E’
meglio attenersi a ciò che potete fare usando questo albero.
La ragione è che i calcs sono effettuati più spesso di quello
che pensate, e inserendo operazioni costose come ricerche,
aggiornamenti di records, comandi SQL, lunghi loop, potete
degradare significativamente le performance di sistema.
38
Un paio di esempi per spiegare l’uso di un calc memorizzato:
Abbiamo una tabella e vogliamo memorizzare una chiave
complessa per ciascun cliente basata sul codice zip e
sull'anno che il cliente è entrato nel sistema. Così per un
cliente con codice zip 94502 entrato nel sistema nel 1997
vogliamo '94502-1997'. Possiamo creare un calc memorizzato
chiamato customer_key di tipo char col seguente metodo:
return zip_code + ' -' +
date_entered.getFullYear();
Ora immaginate che invece di memorizzare quella chiave
nella tabella customer, voleste memorizzarlo nella tabella
ordini. Per fare questo, avrete bisogno di una relazione moltia-uno chiamata orders_to_customers che collega ogni record
ordine al record cliente collegato. Ovvero, il vostro metodo
del calc sarebbe così:
return orders_to_customers.zip_code + ' -' +
orders_to_custo mers.date_entered.getFullYear();
39
Calcoli Non Memorizzati
I Calcs non Memorizzati sono come i Calcs Memorizzati
però non vengono mai scritti nel database, vivono solo in
memoria.Pensate a loro come a 'calcoli di colonne virtuali'
che potete usare nei vostr i metodi e mostrare sulle form ma
che non vengono mai scritti nel db . Sebbene i Calcs non
Memorizzati di solito sono calcolati come colonne e di solito
usati in modalità solo-lettura, questo bisogno non sempre è il
caso. Se lo script di calcolo legge sempl icemente come segue:
poi piuttosto di calcolare un valore per la colonna, Servoy vi
lascerà mettere i valori della colonna nei metodi della vostra
soluzione o, se inserite il calc in un campo di una form (e
rendete Editabile il campo) Servoy permetterà a gli utenti di
registrare i valori del calc. Così ora avete una colonna del
database virtuale che voi o i vostri utenti potete manipolare,
ma che non verrà mai allocata nel database, e che persisterà
solo finchè persiste il foundset. Questo a volte può risultare
molto utile, come dimostrato in questo esempio di
implementazione di checkboxes.
Aggregazioni
Le aggregazioni sono come calc s non memorizzati e ricevono
operazioni di aggregazione (somme, medie, contatori, max e
min) su un foundset di records.
Poniamo di visualizzare un elenco di clienti su una form. Una
delle colonne della tabella customer è chiamata YTD_total e
contiene il valore totale degli ordini di quel cliente inseriti
fino a quest' anno. Si vuole mostrare un totale di tutti i valori
YTD_total nel foundset corrente sulla form. Questi sono i
passi:
Create una aggregazione chiamandola sum_YTD_totals sulla
tabella customer,
40
Inserire una sezione 'Trailing Grand Summary' in cima alla
form
Inserire la aggregazione sum_YTD_totals in un campo
all’interno della sezione 'Trailing Grand Summary' della
form. Presto fatto!
Voi potete usare la stessa aggregazione anche con le relazioni
per aggregare un gruppo di records correlati senza doverli
visualizzare. Costruite l'esempio di cui sopra, con una tabella
chiamata salesreps, e una relazione 'uno-a-molti' tra salesreps
e customers chiamata salesreps_to_customers. Potreste creare
un calc (memorizzato o no, come desiderate) nella tabella
salesreps che calcoli il totale di YTD_totals per tutti i clienti
che appartengono a quel salresrep. Questo il metodo da usare
nel vostro calc:
return salesreps_to_customers.sum_YTD_totals
Variabili Globali
Ci sono due tipi di variabili globali possibili in Servoy, quel lo
che voi dichiarate nella finestra del Dataprovider e quello che
dichiarate in un metodo JavaScript. Le v ars globali dichiar ate
direttamente nel vostro codice JavaScript non vengono
mostrate nell'elenco delle vars globali della finestra del
Dataprovider, né vengono mostrate in qualsiasi altro elenco
all'interno del IDE di Servoy. Sono usati da programmatori
JavaScript avanzati, mentre raccomando ai principianti di non
fane uso.
Le vars globali dichiarate nella finestra di Dataprovider sono
disponibili a tutti i vostri metodi e da tutte le chiamate dai
dataproviders (es. nei campi sulle forme, nelle definizioni
delle relazioni sotto il nodo Globals>>Variable dell'oggetto
albero in Servoy Editor, ecc.).
Voi assegnate una var globale mettendo 'globals.' dav anti al
41
suo nome, come:
globals.lastName = 'Smith';
Le vars globali non persistono quando uscite dall'ambiente di
run-time. Se voi con ctrl-L uscite dall'ambiente di run -time
mentre state scrivendo e testando in debug un metodo,
sappiate che il valore di queste variabili viene convertito in
zero o null, (ciò dipende dal tipo di variabile). Potete
assegnare un valore di default a una var globale nella finestra
del dataproviders, nello stesso luogo dove la create.
Come si assegnano i dataproviders nelle fo rm & metodi
Prendiamoci un pò di tempo per spiegare come assegnare un campo
ai dataproviders nelle form e nei metodi. Per assegnarlo a una
colonna di database così:
database_table_name.column_name
ma Servoy mi ha assegnato la colonna anche in questi modi:
forms.form_name.column_name
e
forms.form_name.relation_name.column_name
e la mia immediata reazione er a di dire 'Ma la colonna fà parte di
una tabella, non di una form! Come f à a sapere quale è la tabella da
assegnare? La risposta è che una form è sempr e collegata ad una
tabella, così voi la state assegnando implicitamente alla tabella.
Inoltre, quando voi dite
forms.customerForm.last_name
voi state infatti assegnando la colonna last_name del record
attualmente selezionato sulla form customerForm. Così p er esempio
se voi voleste settare la colonna last_name a ' Smith ' dovreste fare:
42
forms.customerForm.last_name = 'Smith'
e se voleste inserire il valore della colonna last_name nella var
globale dovreste fare:
globals.cust_last_name = forms.customerForm. last_name
Gli esempi sopra stanno usando il prefisso “forms.customerForm”
davanti al last_name. Se il metodo che contiene il codice appartiene
alla form customerForm, allora potreste omettere il prefisso
“forms.customerForm” e funzionerebbe bene lo stess o. In altre
parole, voi dovreste invece fare così:
last_name = 'Smith'
globals.cust_last_name = last_name
Dovete applicare le stesse regole di si ntassi quando volete assegnare
calcoli o aggregazioni.
Assegnare un Dataproviders a i Records Correlati
Panoramica
Ora guardiamo a come usare le relazioni per assegnare un
record correlato dataprovider a un campo della form .
Ogni form è collegata a una tabella. Anche ogni relazione è
collegata ad una tabella se pensate alla tabe lla sul lato sinistro
della definizione della relazione come sua 'tabella base '. Per
esempio noi possiamo pensare a una relazione
customers_to_orders come ' basata sulla' tabella dei clienti. Le
sole eccezioni sono le relazioni globali che sono ‘basate’ a
una var globale piuttosto che a una tabella. Lasciamo stare
questa parte per il momento.
Se create diverse relazioni basate sulla tabella customer,
come customers_to_orders, customers_to_salresreps,
customers_to_contacts, ecc. queste potrebbero essere tutt e
visualizzate (ad es. sotto un tab relazioni) in qualsiasi delle
43
form collegate alla tabella customer (vedi sotto).
Voi potete usare queste relazioni per assegnare un
dataprovider di tabella correlata (es. una colonna della tabella
sulla parte destra della relazione) con
relation_name.dataprovider_name
Relazioni Molti-a-Uno
Se la relazione è molti-a-uno (come customers_to_salesreps
la quale per ogni record di un gruppo di clienti assegna un
unico record salresrep) allora per fare quest o:
forms.customerForm.customers_to_salesreps.last_n
ame
State dicendo il ‘cognome’ selezionato sulla customerForm
che appartiene alla tabella ‘settori clienti’ correlata alla
tabella ‘clienti’.
44
Come con i dataproviders non correlati , la espressione
forms.customerForm.è necessaria solo se siete in un metodo
che non appartiene al customerForm. Così se voi volete
mettere il cognome (presente nei reparti vendite) sul form
customerForm, dovrete creare un campo e specificar gli come
dataprovider:
customers_to_sa lesreps.last_name
anche quando siete in metodi all’interno della customerForm.
Relazioni Uno-a-Molti
Se la relazione è uno -a-molti (come customers_to_orders che
collega un cliente al gruppo di ordini di quel cliente) allora
potreste voler usare la relazione insieme a un related tabpanel
o a un portale. Potete saltare a la sezione sui tabpanels per
vedere come le relazioni uno -a-molti sono usate con i
tabpanels, perché l'argomento di cui sotto non è previsto. Lo
sto includendo solo per completezza.
Quando voi dite:
forms.customerForm.customers_to_orders.order_dat
e
state dicendo 'la data dell'ordine dal gruppo di ordini del
cliente attualmente selezionato sulla form custo merForm.'
Questa espressione viene usata normalmente nel vostro
codice, ma non la vedrete usata come dataprovider di un
campo su una form. Lasciate che vi spieghi.
Se voi mettete un campo sulla form customerForm il cui
dataprovider è:
customers_to_orders.order_date
mostrerà davvero la data del l 'ordine attualmente selezionato
per il cliente attualmente selezionato', ma cosa intende per
45
'ordine attualmente selezionato'? Se voi non state mostrando
l'elenco degli ordini collegati, l' ut ente non ha il contesto per
sapere quali ordini sono in selezione. Per default, è sempre
l'ordine con la chiave primaria minore fra gli ordini collegati
a quel cliente, ma manca il contesto dal quale il vostro utente
lo può vedere.
Per poter selezionare il secondo ordine del gruppo di ordini
collegati voi potete caricare questo comando in un metodo:
customers_to_orders.setSelectedIndex(2);
e appena fatto questo, il campo order_date del secondo ordine
correlato al cliente (in ordine di chiave primaria) dov rà
apparire sulla form.
Sebbene vi siano situazioni dove questa potrebbe essere
l'interfaccia desiderata, è più comune usare una relazione
'uno-a-molti' per mostrare le informazioni di tutti i records
legati a un parent, oppure mostrare le informazioni co rrelate
ai tabpanels (o ai portali).
Uso di Dataproviders correlati in TabPanels
Ora immaginate di volere mostrare il contenuto d el campo
order_date di ogni ordine collegato a un cliente. Dovreste
creare un tabpanel correlato sul form customerForm collegato
alla relazione customers_to_orders. Nel tabpanel voi inserite
una form collegata agli Ordini, e su quella form mettete un
campo 'order_date' come suo dataprovider. Questo comanda a
Servoy di mostrare nel tabpanel tutti i records degli Ordini
collegati al cliente corrente, e specificamente mostra re la
colonna order_date di ogni record. Notate che non dovete
inserire il seguente comando
customers_to_orders.order_date
Invece, la relazione customers_to_orders è già sp ecificata
nella definizione del tabpanel, e Servoy la usa per la ricerca al
46
momento del caricamento del tabpanel con i records Ordini .
Per dettagli sulla creazione dei tabpanels vedere qui.
Uso di Dataproviders correlati nei Metodi
Ora scriviamo un metodo con un loop per leggere il
contenuto di order_date in ogni ordine collegato al cliente
selezionato, per poter ottenere la data più vecchia.
(Naturalmente potreste fare questo senza scrivere alcun
codice usando una aggregazione correlata, che per il
momento ignoriamo.) In quel contesto voi dovreste scrivere
customers_to_orders.order_date
Di seguito spieghiamo come dovrebbe essere il metodo. In
questo codice di esempio presum iamo che il metodo
appartenga alla customerForm, e così possiamo omettere
'forms.customerForm.'. Presum iamo anche di aver verificato
prima di chiamarlo, che è presente almeno un record ordine
riferito al cliente corrente ( col controllo che
customers_to_orders. getSize() sia maggiore di zero):
var most_recent = new Date(); /* questa var
locale dovrà contenere la data più_recente.
Inizializzata alla corrente datetime. */
for (var n = 1; n <=
customers_to_orders.getSize(); n++)
{
customers_to_orders.setSelectedIn dex(n);/*
questo causa la lettura del record 'n' come
record corrente , e il suo contenuto caricato nel
campo del dataproviders collegato.*/
if (customers_to_orders.order_date <=
most_recent)
{
most_recent =
ustomers_to_orders.order_date;
}
47
}
return most_recent;
Uso di Relazioni e Dataproviders Nidificate
Nella sezione relazioni nidificate, spieghiamo come potete
concatenare insieme delle relazioni per arrivare a un
dataprovider più distante, come questo:
relation1.relation2.relation3.dataprovider
Uso del selectedrecord per assegnare un Dataproviders
In Servoy Editor, se voi cliccate sul nodo “selectedrecord”
sotto qualsiasi form dell'oggetto albero, voi vedrete l'elenco
di dataproviders per la tabella alla q uale la form è collegata.
Vengono incluse le colonne del database, calcs memorizzati,
calcs non memorizzati e aggregazioni. Voi potete inserire la
referenza di un dataprovider nel vostro metodo
semplicemente con un doppio -click sul dataprovider di
questo elenco.
Elementi
Quando cominciai a imparare Servoy avevo la difficoltà di capire la
differenza tra dataproviders e elementi. Questo perchè un
dataprovider e un elemento possono avere lo stesso nome, e questo
crea confusione nel decidere quando usarli. Ne l caso voi aveste lo
stesso problema, questa sezione intende chiarirlo.
Un dataprovider è un contenitore che contiene dati. Questi possono
essere messi ovunque, in una colonna del database , all'interno di
form, di var globale, di calc o aggregazione. Un elemento è un
oggetto visuale su una form come un campo, un'etichetta, un
bottone, portale, tabpanel, javabean, un grafico, ecc.. Dovete
assegnare un nome a un elemento della form se poi vol ete
manipolarlo (es. controllare la sua visibilità, ordinarlo in ordine di
grandezza, colore, posizione, se editabile, ecc.)
48
Poniamo di lavorare su una form chiamata customerForm collegata
alla tabella customer. Quando aggiungete campi alla form usando il
Elements/ field, vi offre la possibilità o meno di inserire il no me per
ognuno dei campi aggiunti alla form. Se selezionate questa scelta
mentre aggiungete un campo “ last_name” alla vostra form, voi
avreste un campo il cui nome è last_name e il cui dataprovider si
chiama 'last_name'. Questo può creare un pò di confusion e.
Ciò che molti sviluppatori fanno è di nominare gli elementi di un
form cliccando su ognuno di essi e inserendo un nome nella
proprietà name del pannello della proprietà. (Vedere la sezione
convenzioni sui nomi per ulteriori informazioni su questo
argomento). Voi potreste usare il prefisso 'fld' quando nominate un
elemento di campo (es. fldLastName e fldFirstName), un prefisso
'lbl' per elementi di etichetta (es. lblLastName, lblFirstName) e 'btn'
per i bottoni (es. btnLookupAccountBalance). Avendo fatto
questo, voi potete modificare ad esempio le proprietà del campo
così:
forms.customerForm.elements.fldLastName.visible =
true
forms.customerForm.elements.fldLastName.setFont('Aria
l')
ma potete ottenere o modificare il valore della colonna last_name
(o dataprovider, usando la terminologia di Servoy) come segue:
forms.customerForm.last_name = 'Smith'
// settaggio della colonna last_name del record
corrente a 'Smith'
globals.cust_last_name = forms .customerForm.last_name
/* inserisce la colonna last_name del record corrente
nella variabile globale globals.last_name. * /
Gli esempi sopra mostrano il “forms.customerForm” col prefisso
solo per chiarezza. Se il metodo che contiene il codice è un metodo
della form customerForm, allora voi potreste sempre omettere il
prefisso “forms.customerForm” e funzionerebbe lo stesso. In altre
49
parole, voi potete modificare le proprietà dei campi così:
elements.fldLastName.visible = true
elements.fldLastName.setFont( 'Arial')
e voi potete ottenere o modificare il valore della colonna di database
last_name così:
last_name = 'Smith'
// setta il contenuto della colonna last_name del
record corrente a 'Smith'
globals.cust_last_name = last_name
/* mette il valore di last_ name del record corrente
nella var globale (predefinita) globals.last_name.*/
In Servoy Editor, se cliccate sul nodo “elements” di qualsiasi form,
vedrete l'elenco degli elementi nominati su quella form. Quando
cliccate su un elemento, vedrete le sue prop rietà e le sue funzioni
elencate sotto. Voi potete inserire la istanza di una proprietà di un
elemento o di una sua funzione nel vostro metodo semplicemente
con un doppio-click sull'elemento desiderato di questo elenco.
by Adrian McGilly , Servoy Consultant & Trainer
Copyright 2006, All Rights Reserved [TOP]
50
51
52
53
54
Molti Controllers, Meno Tempo
by Adrian McGilly
È facile confondersi tra i vari oggetti della form che possiedono la
parola 'controller' al loro interno, essi sono:
• oggetto controller
• oggetto currentcontroller
• controller form (in Servoy versions precedente a 3.x)
Queste le differenze:
Oggetto c ontroller
Ogni form possiede un controller. Questo non è un oggetto che
potete vedere sulla vostra form, come un campo o un b ottone. È
visibile solo nell'oggetto albero di Servoy Editor sotto ogni form.
Il controller di una for m è una raccolta di proprietà e di metodi
che agiscono sulla form e sul suo foundset. Essi includono:
controller.find()
controller.search()
controller.deleteRecord()
controller.setSelectedIndex()
etc.
Oggetto c urrentcontroller
currentcontroller significa 'il controllore della form corrente, e per
'form corrente' significa la form che è attualmente visibile. (Ci
possono essere al massimo due form visibili se voi includete una
form mostrata all'interno di un dialog con showFormInDia log(),
ma non è il nostro caso)
Questo oggetto è utile quando il vostro codice ha bisogno di fare
qualche cosa alla form che è attualmente visibile, ma non potete
sapere in anticipo ciò che quella form farà a un dato momento.
[TOP]
55
Per esempio, poniamo che state scrivendo un metodo globa le che
è responsabile di stampare il contenuto della form corrente.
Potreste usare currentcontroller.print() che r ichiama il metodo
print() dell'attuale form visibile.
In alternativa, poniamo di aver creato il metodo di stampa
chiamato myPrint in ciascuna form della vostra soluzione, e
supponiamo che volete un metodo globale che richiami il metodo
myPrint della form corrente. Come fare se non sapete quale sarà
la form corrente in quel momento? Potete usare
currentcontroller.getName() per ottenere il nome d ella form
attuale, e poi siete pronti per costruire una chiamata al metodo
myPrint del vostro form. Così:
var formName = currentcontroller.getName()
forms[formName].myPrint()
(Sto usando il fatto che i raggruppamenti nell'albero di Servoy
Editor come 'for ms', 'elements', 'tutti i dataproviders' possono
essere trattati come schiere. Così forms.myForm è lo stesso che
dire forms[‘myForm’].)
Controller Form
L'ultimo oggetto con nome ‘controller' è il controller della form.
Fino al 2.2.5, ogni form ha una propr ietà nel pannello della
proprietà chiamato controller. Qui si può specificare il no me di
una speciale form che si vuole che appaia alla sinistra della vostra
form ogni volta che viene aperta. Normalmente il controller form
viene adoperato come tool per po ter agilmente navigare attraverso
i dati della form principale. Dal 3.x è stato cambiato il nome della
proprietà a Navigator e la form a Navigator.
by Adrian McGilly , Servoy Consultant & Trainer
Copyright 2006, All Rights Reserved [TOP]
56
57
Come & Quando il salvataggio dei Dati
Modificati
by Adrian McGilly
Panoramica sui Salvataggi in Servoy
Nota: l’argomento ha subito cambiamenti dal 3.x, riferirsi a lla fine
di questo capitolo per il funzionamento nel 3.x. (Quando parleremo
di salvataggio si intenda: attuazione delle modifiche effettuate ).
Per ora, presumiamo di non stare usando operazioni del db. La
discussione sull' uso di operazioni del d b è più avanti, ma si
dovrebbe leggere prima questa sezione.
Poniamo che un utente abbia modificato o aggiunto un record su
una form. Il comportamento di default di Servoy salva le modifiche
o le aggiunte fatte dagli utenti appena cliccano su qualsiasi pa rte
della form, o appena si esce dal record in elaborazione. Il
salvataggio viene eseguito solo quando viene modificato o aggiunto
ogni record, non in altri casi.
Le azioni dell'utente che determinano il salvataggio sono:
• navigare ad un altro record nella stessa form
• aggiunta di un altro record
• cancellazione di un record
• compiere una ricerca
• navigare a un altro form
• chiudere la soluzione
• uscire da ambiente Servoy
La stessa regola del salvataggio dati è valida in Servoy per le
[TOP]
58
modifiche eseguite all'intern o dei metodi. Se il metodo fà una
modifica a un record, i cambiamenti saranno salvati al db appena il
metodo o l'utente esegue qualcuna delle azioni elencate sopra.
Per esempio, se il vostro metodo modifica un record A e poi
seleziona un rec B (usando con troller.setSelectedIndex () ), i vostri
cambiamenti vengono salvati al momento che B viene selezionato.
Considerate questo metodo:
controller.newRecord()
name = 'ABC Company'
city = 'Fremont'
return;
Immediatamente subito dopo il compimento del primo comando di
aggiunta record, voi vedete 'ABC Company' e 'Fremont' che
vengono inseriti nei loro rispettivi campi sulla form, ma sia questi
valori che il nuovo record stesso non vengono salvati
effettivamente sul db fino a quando un metodo o un utente compie
una delle azioni sopra elencate.
Un altro esempio:
controller.newRecord()
name = 'Furtado Auto Supply'
city = 'Livermore'
controller.newRecord()
name = 'Honest Ed Auto Repair'
city = 'Larksp ur'
return;
Immediatamente dopo il compimento di questo metodo, il record
'Furtado Auto Supply' viene già salvato nel db, invece quello
'Honest Ed' sebbene visibile sul form, non viene salvato ancora.
Ora guardiamo alla cancellazione e Controller.delet eRecord()
cancella immediatamente il record sia dal foundset che dal db – non
è necessario nessun salvataggio esplicito nè altre azioni.
59
Preferirei però usare controller.saveData() esplicitamente alla fine
del metodo che ha modificato i dati, giusto per essere sicuro. Ci
sono delle importanti eccezioni alle regole sopra descritte.
Uso del setFocusLostSaveEnabled(false)
C'è la funzione application.setFocusLostSaveEnabled() che può
essere usata per cambiare il comportamento su esposto. Se inserite
questo comando con false, dite al sistema di bloccare il salvataggio
delle modifiche ogni qualvolta l'utente clicchi su un'area vuota della
form. Le modifiche però continuano a essere salvate
automaticamente quando l'utente compie qualcuna delle azioni per
uscire dal record modificato/aggiunto specificate nell’elenco sopra.
Uso di Transactions
Se state usando transactions, allora tutto ciò detto sopra viene
applicato, a meno che le modifiche siano state effettu ate all'interno
di una transactions non ancora connessa al db , ciò determina il
reale salvataggio dei dati solo alla effettiva connessione al database.
Se fate diverse modifiche (es. aggiunte, cancella zioni, modifiche)
all'interno di una transaction, esse interesseranno il foundset ma
non il db fino a quando eseguirete un commit.
Inoltre, se la transaction è annullata(rolled back ), i cambiamenti
effettuati vengono annullati anche loro, sia nel foundset che nel db.
I comandi per gestire le transactions sono:
Command
Description
databasemanager.startTransaction()
Lancia una nuova
transaction
databasemanager.commitTransaction()
Conferma esecuzione
corrente transaction
databasemanager.rollbackTransaction()
Annulla la transaction
60
Cambiamenti in Servoy 3.x
Con Servoy 3.x molte cose sono cambiate. Servoy ha aggiunto una
opzione chiamata autoSave con la quale potete attivare oppure no i
salvataggi automatici con
databaseManager.setAutoSave(boolean).
Quando autoSave è on, attua il comportamento descritto per la
versione 2.2.5. Quando autoSave è off, Servoy blocca i salvataggi
in proprio–essi dipenderanno da quel punto in poi dal comando
saveData() con un parametro di temporizzazione per il db server.
Questo è stato fatto per permettere di armonizzare il
comportamento del rich client con quello del web cliente. Nel web
client, Servoy non può sapere che un utente sta “uscendo da l
record”, questo è possibile nel rich client, e perciò in questo caso
non può offrire il salvataggio automatico dei records sui forms che
girano sul web client. Settando il comando autoSa ve in off si fà in
modo che le form si comportino allo stesso modo a riguardo del
salvataggio dei dati, sia nel rich client che nel web client.
Se mettete autoSave in on o in off, voi lo fate per la vostra intera
soluzione . Se desiderate settare a on alcune form e a off altre, voi
lo potete fare alla apertura e alla chiusura di ciascuna form.
Servoy ha presentato un secondo uso del comando saveData().
Prima del 2.2.5 il comando saveData faceva parte dell'oggetto
controller e così forms.customerForm.controller.saveData() salv ava
le modifiche eseguite solamente sulla form customerForm.
Il nuovo comando presentato col 3.x è databaseManager.saveData ()
che salva le modifiche su tutte le form.
by Adrian McGilly , Servoy Consultant & Trainer
Copyright 2006, All Rights Reserved [TOP]
61
Convalida dei Record Prima di Salvare
by Adrian McGilly
Panoramica sulla Convalida dei Dati
Servoy possiede alcuni controlli di questa funzionalità risultata un
pò debole nella versione 2.2.5 mentre è stata migliorata nel 3.x.
I principianti, dovrebbero fare localmente la convalida , con i
metodi JavaScript. Se vi aspettate che il vostro db spedisca
messaggi su UNIQUE o sulle violazioni di NOT_NULL e
REFERENTIAL INTEGRITY , esse saranno nella forma brutale
“Cannot save form data” che riporta il messaggio dir etto dal
database–non qualcosa che desiderate per i vostri utenti. Nel 2.2.5
non c'era questa modalità. (Nel 3.x si possono intercettare i
messaggi del database e gestirli in modo elegante. Non ho ancora
usato questa funzionalità del 3.x quindi non ho ancora elementi per
giudicare.)
Ci sono tipicamente, due livelli di convalida –a livello di campo e a
livello di record. La convalida a livello -campo è quella dove
controllate che ogni singolo campo contenga un giusto valore, e la
convalida a livello-record è dove controllate che i valori del campo
siano congrui con il valore degli altri campi –per esempio
controllare data di inizio e data di fine, con la data di inizio
inferiore della data di fine. Servoy permette la convalida di
entrambi i livelli.
Per la convalida a livello-campo, potete collegare un metodo di
convalida all'evento onFocusLost (alla uscita dal campo) o
all'evento onDataChanged ( appena il contenuto del campo viene
cambiato). Potete fare poi i vostri controlli di convalida all'interno
del metodo collegato all'evento del campo e se la convalida fallisce
e volete permettere all'utente di lasciare il campo, inserite il
seguente comando:
elements.your_field_element_name.requestFocus();
[TOP]
62
Voi non potete fermarlo. Questi eventi a livello -campo lanciano il
metodo solo se state lasciando un campo per andare a un altro
campo dello stesso record. Invece se cliccate su un tasto che vi
porta su un altro record o su un altro form, o se siete in list view o
table view e cliccate su un campo di un record divers o dell'elenco,
tutti questi eventi non lanciano. Così anche se aggiungete tutti
questi controlli a livello -campo, siete costretti per sicurezza a
controllare di nuovo i campi per la convalida a livello -record.
La miglior convalida a livello-record è l'evento onRecordSave.
Questo evento funziona ogni volta che si esce dal record
modificato. Viene applicato senza controllare COME si esce dal
record, e senza controllare se si sta mostrando il record in modalità
record view, list view or table view. Per esempio, se parliamo di un
record (in list view or table view) e si esce da esso cliccando su
un’altro dello stesso elenco, oppure su un qualsiasi record della
stessa form, o si è cliccato su un bottone che vi porta su di una
diversa form. L’evento onRecordSave lancerà con nessun riguardo
a come l'utente lascia il record.
L'unico problema era prima del 2.2.5, dove non c'era alcun modo di
dire all'evento onRecordSave di non salvare il record se falli va la
convalida. Potevate fare il vostro metodo di convalida per
controllare la validità di un dato, ma quando l'esecuzione finiva,
Servoy salvava lo stesso i dati. Questa era una svista , che rendeva
la convalida del livello -record molto difficile. Dal 3.0 è stato
modificato questo evento così che se il meto do collegato ad esso
riceve un false evita il salvataggio .
Tre differenti approcci
Ci sono alcuni modi di lavorare su questo probl ema. Di seguito i tre
migliori:
Fare modifiche e aggiunte con una finestra di dialogo
Potete fare tutte le modifiche in Record View usando una
63
finestra di dialogo .
application.showFormInDialog(forms.formName)
dove mostrate la form specificata in una finestra di dialog.
Così se la form specificata contiene il record che è stato
aggiunto/modificato, questo approccio mantiene la sicurezza
per l’utente nell’inserimento e nella modifica del record
essendo limitato ogni volta a un solo record su ogni form.In
questo caso voi avrete bisogno di mettere un paio di tasti
salva & cancella sulla form, e quando si preme il tasto salva,
voi potete lanciare la convalida e salvare i dati col comando
controller.saveData() se la convalida risulta giusta.
Bloccare o intercettare tutti i punti di uscita dal record
Un altro approccio è la modifica/aggiunta con una normale
form sulla quale inserire i tasti salva & cancella (o sulla form
controller, se la state usando) per verificare che l'utente non
possa andare da alcuna parte prima che l’operazione sia stata
salvata o annullata. Di seg uito vengono presentate alcune
tecniche per realizzarlo:
1. Non si permette all'utente di lasciare la form se si
riceve un false dal metodo e poi collegarlo ad esempio
all’evento onHide. In questo modo, se quel metodo
potesse controllare la convalida, allora in caso
negativo potrebbe mostrare un messaggio bloccante
che non permetta all’utente di lasciare la form.
2. Si può disabilitare una intera form settando la
proprietà enabled a false. Questo può essere utile con
una controller form o una form all’interno di un tab panel con i tasti per la navigazione e si vogliono subito
disabilitare tutti quei bottoni.
3. Si vorrebbe anche prevenire l'utente dall’effettuare le
operazioni dal menu Select (come Next, Previous,
New Record, ecc.) per aggiornare o inserire ogni
64
record. L'unico modo per prevenire queste operazioni,
è quello di esaminar e ogni metodo che viene lanciato
dal corrispondente evento (es. onNextRecordCmd,
onPreviousRecordCmd, onNewRecordCmd, ecc.) e
per ogni metodo esaminare se il record corrente è in
stato non valido prima di procedere col percorso
normale.Per esempio, si potr ebbe usare l'evento
onNewRecordCmd per chiamare il vostro metodo
myNewRecordCmd, e questo metodo dovrebbe
esaminare prima se il record corrente è in uno stato
non valido. In tal caso, dovrebbe avvertire l'utente con
un messaggio bloccante. Altrimenti, crea re un nuovo
record usando controller.newRecord.
4. Attenzione perchè scegliendo questo approccio userete
application.setSaveOnFocusLostEnabled(false)
(discusso sotto) perché altrimenti, nel momento in cui
un utente clicca sul proprio tasto save Servoy lancerà il
salvataggio del record e bypasserebbe così la vostra
convalida.
Uso delle transazioni
Forse l’ approccio più semplice è di usare una transazione.
Se includete un add o un edit in una transazione, allora non
dovete più preoccuparvi di un salvataggio prematuro dei
vostri dati perché al momento del fallimento della convalida
potete ritornare indietro al onRecordSave. Attenzione perchè
questo non impedirà al db di generare errori, come violazioni
di record unique o violazioni di campi not_null durante il
salvataggio dati, così avrete bisogno di verific he come
spiegato di seguito qui.
Funzione setSaveOnFocusLostEnabled()
La funzione application. setSaveOnFocusLostEnabled () controlla
la chiamata di onRecordSave . Se è messo a true, onRecordSave
agirà nel momento in cui l'utente va su un altro record o clicca su
65
una parte libera della form. Se è messo a false, quella stessa azione
non attiverà onRecordSave.
Comportamento di Modifiche e Salvataggio Prima del 3.x
Ci sono un paio di importanti miglioramenti in quest o argomento
nella versione 3.0. Il più importante è, come menzion ato sopra, che
voi ora potete fermare l'evento onRecordSave per compiere un
salvataggio semplicemente restituendo un false al metodo
onRecordSave. Inoltre, come menzion ato in una precedente sezione
del manuale, la versione 3.0 ci lascia “spegne re autoSave”, e se voi
avete il completo controllo dei dati–essi non saranno MAI salvati
senza il vostro esplicito comando di saveData. Queste due migliorie
renderanno più facile la implementazione di convalida a livellorecord.
by Adrian McGilly , Servoy Consultant & Trainer
Copyright 2006, All Rights Reserved [TOP]
66
Verifica Univocità di un Record
by Adrian McGilly
Quando aggiungendo o modificando un record , spesso avrete
situazioni dove vorrete verificare che una certa colonna o gruppo di
colonne sia unico per quella ta bella. Come fare questo in Servoy?
Ci sono diversi modi per farlo.
Se non vi importa che i vostri utenti ricevano un brut ale messaggio,
potete mettere la restrizione uniqueness sulla tabella del vostro db e
potete contare su quella. In questo caso, quando salvate il record , i
vostri utenti riceveranno un bip e un messaggio di errore simile a
“non si possono salvare Dati del Form”. Se l'utente clicca sul tasto
“ Details” sotto il messaggio vedrà un messaggio del database che
cita una violazione della restrizione. Non è molto bello.
Sfortunatamente in 2.2.5 non vi è modo di “intercettare” questi
messaggi del db per poterlo presentare meglio all'utente. (Questa
funzionalità comincia dal 3.x)
L'altro approccio deve verificare l' uniqueness interrogando il
database per vedere se ci sono records duplicati prima del
salvataggio di un nuovo record. In tal caso, voi dichiarate una
violazione di uniqueness all’utente nel modo migliore che ritenete ,
e ritornate all'utente il record senza salvarlo. Altrimenti lo salvate.
Questo sembra abbastanza semplice, ma c'è un inghippo. Poniamo
che il vostro utente abbia aggiunto un nuovo record su una form
customerForm, la quale è collegata alla tabella Customer. Lui
riempe i suoi campi inserendo ‘ACME Tools’ nel campo
company_name. Poi preme il tasto save. Voi avete già
programmato il tasto save per verificare l'uniqueness del
company_name prima di salvare il record. Voi fareste così:
// inserisce il campo del nuovo record in una var
locale
var co = company_name
67
controller.find();
// lancia una sessione di
ricerca
company_name = co;
// gli dice di cercare su
company_name = co
controller.search(); /* lancia la ricerca e mette i
risultati nel foundset corrente */
if (controller.getMaxRecordIndex() )
{
plugin.dialog.showErrorDialog('Uniqueness
Violation', 'C’è già una s ocietà con il nome ' + co,
'OK');
}
else
{
controller.saveData();
}
Il motivo per cui non eseguirà il lavoro è che nel processo di
ricerca dei records duplicati, voi avete già pulito il foundset
precedentemente contenut o nella form, quando il foundset
conteneva il nuovo record. Quando il vostro metodo arriva al
comando savedata(), non avrà più accesso al nuovo record che
volevate salvare.
Nell'esempio di cui sopra, l'utente aveva aggiunto un nuovo record.
Lo stesso si applica se l'utente modifica un record esistente, e voi
volete verificare l' univocità del record modificato .
Ora, rimanendo sull’esempio di sopra (controllo della univocità
della colonna company_name della tabella Customer sul form
customerForm) vi mostrerò un paio di modi per controllare
uniqueness senza toccare il vostro foundset:
Approccio #1 – scrivere una generica funzione
checkUniqueness() con SQL
Potete usare una query SQL per determinare la univocità. Le query
SQL si lanciano con databaseManager.getDataSetByQuery () senza
interferire con i foundsets (a meno che non lo richiedete!).
databaseManager.getDataSetByQuery () lancia una query SQL al
68
vostro db e ottiene indietro come risultato un dataset. Per default,
questo comando non concerne foundsets in alcun modo così
funzionerà perfettamente nella nostra situazione.
Poniamo di avere una form customerForm con un metodo della
form chiamato “Sa ve” di cui supponiamo esaminare l’univocità di
company_name della tabella Customer . Se risultasse unico, il
record sarebbe salvato, altrimenti mostrerebbe un messaggio di
errore. Nell’esempio successivo usiamo una funzione SQL . La
funzione count(*) è una funziona SQL standard per contare tutt i i
records che vengono confrontati col criterio determinato dalla
clausola where. Il metodo dovrebbe essere così :
/* conta il numero di records con uguale contenuto
di company_name .
Questa query deve ritornare un numero, così il
dataset risultante sarà una schiera 1 x 1.
*/
var query = 'select count(*) from Customer where
company_name = ' + company_name;
var resultDataSet =
databaseManager.getDataSetByQuery(
controller.getServerName(), query, null, 1);
/* la funzione getValue prende come suo parametro un
numero di record e un numero di colonne e
restituisce il valore nella casella del dataset.
Se è uguale a zer o, allora nessun record trovato nel
db significa che quel record creato è unico.
*/
if (resultDataSet.getValue(1,1) == 0)
// testa il
numero di record contati
{
// il record è unico
controller.saveData();
}
else
{
plugins.dialogs.showErrorDialog('Error', 'Un
cliente con company name ' + company_name + '
esiste già. ', 'OK');
69
}
Ora starete pensando “que sto è un terrificante insieme di codice per
esaminare l' univocità di un record!” e avete ragione. Ma questo si
potrebbe ridurre tutto a una chiamata di una riga mettendo tutto
questo codice in una funzione globale “checkUniqueness”. Una
volta fatto, il vostro test sulla univocità sarà semplice come questo:
if (globals.checkUniqueness('Customer',
'company_name', company_name))
{
controller.saveData();
}
else
{
// show your error dialog here
}
Questa funzione adopera come parametri il nome ta bella, il nome
colonna e il valore che deve essere esaminato nei dati, e restituisce
vero se il record è unico, e falso se non lo è. La funzione sarà:
/***************************************
FUNCTION: globals.checkUniqueness()
SCOPO: controlla se un record è unico per una data
tabella. Restituisce true se si, false se no
PARAMETRI:
1. nome tabella,
2. nome di colonna che deve essere u nico,
3. valore del test for uniqueness
ESEMPIO DI CALL:
Il seguente codice di esempio restituisce true se
non ci sono righe in tabella client con il valore
'Smith' nella colonna name :
globals.checkUniqueness('clients', 'name', 'Smith')
************ ****************************/
70
var tableName = arguments[0]
var columnName = arguments[1]
var columnValue = arguments[2]
/*Nelle prossime due righe di codice facciamo uso di
una caratteristica della getDataSetByQuery che rende
più facile legare i nomi del le colonne ai valori
delle costanti all’interno della clausola WHERE
mettendo dei punti interrogativi dove volete che
appaia il vostro literal(s), e inviando il literal
come terzo parametro di getDataSetByQuery. Questo
parametro sarà una schiera perchè abbiamo posto
columnName in [] – e questo crea una schiera con
columnName come suo unico membro. Il primo parametro
è currentcontroller.getServerName() la quale
restituisce il nome del db server al quale la form è
collegata.*/
Questo parametro deve essere un o rdine che è perchè
noi mettemmo columnName in [] –questo crea un ordine
con columnName come il suo unico membro.
var query = 'select count(*) from ' + tableName + '
where ' + columnName + ' = ?';
var resultDataSet =
databaseManager.getDataSetByQuery(
currentcontroller.getServerName(), query,
[columnName], 1)
if (resultDataSet.getValue(1,1) == 0)
//restituisce
il valore nella singola -casella dataset. Se è uguale
a zero, allora non ci sono matching record nel db
così il record creato è unico.
{
return tr ue;
}
else
{
return false;
}
Se ne aveste voglia, potreste migliorare questa funzione per
supportare costrizioni di uniqueness di colonne -multiple
permettendo la chiamata per spedire i nomi di colonne multi ple e il
71
valore di colonne multiple ognuna all’interno di una schiera.
Qualche cosa da tentare nel vostro tempo libero!
Approccio #2 – uso di una relazione per test di uniqueness
Voi potete creare una relazione globale di test per uniqueness.
Questo vi risparmia la scrittura di codice SQL, però dovete creare
una relazione per ogni colonna di cui desiderate esaminare
l’univocità. (Le relazioni sono discusse e molto dettagliate nel
capitolo chiamato Le Relazioni – voi potreste leggerlo e poi ritornare
qui.)
Il nostro esempio, dovrebbe essere:
1. Creare una var globale chiamata testValue.
2. Creare una relazione testValue_to_company_name
3. Settare la chiave primaria ( lato sx) con globals.testValue
4. Settare la chiave esterna (lato dx) con la colonna
company_name della tabella customer
Ora avete una relazione che punta a tutti i records di Customer la
cui colonna company_name si accoppia con globals.testValue. Voi
potete usare questo per esaminare l' univocità di quel valore
esaminando la ‘size’ delle relazioni del foundset usando la
funzione getSize().
Tornando al nostro esempio: l ’utente ha appena inserito un record
Customer e lanciato il salvataggio. Voi volete esaminare l'univocità
del campo company_name. Qu esto è il vostro metodo:
if (testValue_to_company_name.getSize () == 0)
{
// il record è unique
controller.saveData
}
else
{
// il record non è unique. Visualizza error
72
msg, ecc.
}
Potete naturalmente riutilizzare globals.testValue in qualsiasi altr a
relazione globale di cui avete bisogno per esaminare l’univocità di
altre colonne.
Approccio #3 – uso di foundset separato per ricercare matching
record
(Questo approccio gira in 3.x con autoSave a off. Non in 2.2.5
perché lancia un salvataggio che aggira le regole di convalida)
Se nessuno di questi approcci vi attrae, e volete seguire la modalità
base con i comandi find() /search () per esaminare l’univocità, voi
potete farlo in modo da non disgregare il foundset della form che
contiene il nostro nuovo record. Voi potreste, per esempio, crear e
una form nuova collegata alla tabella Customer, attivare la sua
proprietà useSeparateFoundset e lanciare la find() /search() usando
il controller di quella form. Di seguito viene evidenziat o:
La form sulla quale il record è stato inserito è customerForm, ed è
la form attualmente mostrata. La form sulla quale voi farete la
find()/search() per determinare l’univocità sarà
customerLookupForm. Di seguito vi è un metodo sulla form
customerForm per esaminare l’univocità del campo
company_name:
var co = company_name
customerLookupForm.controller.find()
customerLookupForm.company_name = co
customerLookupForm.controller.search()
if (customerLookupForm.controller.maxRecordIndex ==
0)
{
/* il record è unique, così lo salvate usando
il controller del form attuale mostrato ,
customerForm*/
73
controller.saveData
}
else
{
// il record non è unique - mostrate error msg,
ecc.
}
by Adrian McGilly , Servoy Consultant & Trainer
Copyright 2006, All Rights Reserved [TOP]
74
Come Trovare le Date
by Adrian McGilly
Panoramica sulle Date in Servoy
Questa sezione tratta d ella ricerca sulle date, un utente cerca su una
form, o lo sviluppatore codifica la ricerca all’interno di un metodo.
Prima di andare avanti, avete bisogno di sapere due importanti cose
sui campi delle date in Servoy:
• Per default, Servoy usa campi datetime (non campi date) per
memorizzare le date.
• Il formato di visualizzazione di un campo data dipende dal
modo con cui i dati sono stati inseriti nel campo e viene
interpretato sia in modifica che in ricerca per quel campo.
Prendiamoli in considerazione uno per volta .
Servoy per default usa campi datetime
Per default, quando create campi data in Servoy state in
realtà creando campi datetime, cioè nel medesimo campo
verranno allocati la componente data e la componente tempo:
2005-12-20 00:00:00.000
oppure
2006-03-14 17:23:45.212
(le ultime tre cifre sono in millisecondi). Per il resto di questa
discussione noi toglieremo i millisecondi poichè vedremo
che non vengono quasi mai usati nelle applicazioni.
Quando compilate i dati nelle form e inserite la data in un
[TOP]
75
campo datetime, per default nel campo non sarà registrato
alcun componente tempo. Così se inserite
12-20-2005
per default Servoy dovrà allocare nel campo
12-20-2005 00:00:00
È più probabile vedere la componente tempo in un campo
data quando un metodo registra un timestamp (e s. timestamp
di modifica, timestamp di creazione.
Consiglio: Servoy registra automaticamente per voi il
timestamps di modifica e di creazione - guardate alle
particolari colonne in molte tabelle del database , si vedrà che
quei valori vengono inseriti automaticamente dal sistema .)
Il formato di visualizzazione date può essere gestito
In secondo luogo, dovete sapere che il formato col quale le
date sono mostrate (es. MM-dd-yyyy) sulle form viene
controllato dallo sviluppatore . È indipendente dal formato
delle date nel db.
Controllate la visualizzazione di default dei campi
configurando gli opportuni parametri in Modifica>>
Preferenze, ma voi avete la priorità sulla configurazione di
default per modificare il formato dei campi data su qualsiasi
form specificando un formato di visualiz zazione diverso.
76
Da notare che la modifica del formato fatto su uno specifico
campo, riguarderà solamente quell’elemento di campo, su
quella form. Se avete una colonna 'start_date' di database che
compare su diverse form, essa può possedere, se necessario,
un formato diverso su ciascuna form.
(Il formato col quale il db memorizza la data è indipendente
dal formato di visualizzazione , e varia da fornitore a fornitore
ma lo sviluppatore Servoy è indipendente da questo .)
Ora che conosciamo queste due cose importanti sulle date in
Servoy, possiamo vedere la ricerca sulle date.
77
Dobbiamo vedere separatamente due situazioni: quella dove un
utente inserisce i criteri di ricerca su una form, e quella dove si
programma la ricerca in un metodo .
La ricerca delle date per gli utenti
Se un utente inizia una ricerca di date e inserisce la data in un
campo datetime, Servoy capisce che si deve usando lo stesso
formato della data uguale a quello inserito. Così, se inserite
12-05-2005
in un campo configurato con MM-dd-yyyy, sarà interpretato come
Dic. 5, 2005 ma se il campo è configurato come dd -MM-yyyy, i
dati inseriti saranno interpretati come Maggio 12 , 2005.
Se volete essere sicuri, potete specificare il formato desiderato
usando il carattere pipe ‘| ' seguito dalla stringa di configurazione.
Così si potrebbe scrivere
12-05-2005|MM-dd-yyyy
e così costringerebbe Servoy a interpretare il vostro criterio di
ricerca come Dic. 5, 2005.
Negli esempi sopra esposti, se non si specifica la componente
tempo nei criteri di ricerca, Servoy sa che volete la componente
tempo ‘azzerata’ e restituirà così i records con il contenuto
12-05-2005 00:00:00.
E questo per qualsiasi record, anche per quei record che con data
12-05-2005 contengono la componente tempo diversa da zero.
Se l'utente vuole una ricerca su un range di date, egli può inserire
12-05-2005…12-10-2005
oppure
12-05-2005…12-10-2005|MM-dd-yyyy
78
In questo caso, Servoy restituisce tutti i records contenuti nel range
dal 12-05-2005 00:00:00.000 al 12-10-2005 23:59:59
Voi potete usare anche i caratteri <, >, = <, >= nei range come
criteri di ricerca. Questi sono spiegati in Developer User Guide.
Programmare la ricerca delle date in un metodo
L'unica cosa che cambia quando voi state programm ando la vostra
ricerca in un metodo è che dovete specificare il formato della data
con il carattere pipe ’|’. Diciamo che volete ricercare end_date =
’12-05-2005 '. Se il vostro codice è:
controller.find()
end_date = '12 -05-2005'
controller.search()
la vostra ricerca fallirà. Per la ricerca codificata voi dovete
specificare il formato della data usando il carattere pipe. Così
sarebbe corretto:
controller.find()
end_date = '12 -05-2005|MM-dd-yyyy'
controller.search()
Date con la componente tempo
Se la colonna di datetime che è l'obiettivo della vostra ricerca
contiene un valore NON-ZERO nella componente tempo (es. nel
caso di una creazione/modifica timestamp), ci sono considerazioni
da fare nel caso la ricerca venga eseguita non più su singole date,
ma su un intervallo di tempo misurato in secondi. Ad es. se
ricercate
12-05-2005|MM-dd-yyyy
vuol dire 12-05-2005 00:00:00, e che è il solo valore usato come
criterio. Un record che contiene 12-05-2005 11:33:44 non sarà
restituito, anche con data valida.
79
Se voi chiedete
12-05-2005…12-06-2005|MM-dd-yyyy
che vuol dire dal 12-05-2005 00:00:00 al 12-06-2006 00:00:00, che
vanno oltre 24 ore intere del 12-06-2006! Per questo occorre
essere accorti.
Ci sono alcuni modi per gestire questo.
1. Potete dire ‘non mi interessa il tempo, ma solo la data’, così
dovete mettere un carattere ‘#’ all’inizio della vostra stringa
di ricerca. Così per cercare
#12-15-2005|MM-dd-yyyy
restituisce tutti i valori datetime che cadono sul 12-15-2005,
per qualsiasi componente di tempo. Anche per cercare queste
date
#12-15-2005…12-16-2005|MM-dd-yyyy
restituisce tutti i valori della componente tempo che cadono
dal 12-15-2005 thru 12-16-2005 incluso.
2. Voi potete aggiungere un giorno alla fine del vostro range di
ricerca. Se ciò che volete realmente è dal 12-15-2005 al 1216-2005, potreste ottenerlo dicendo
12-05-2005…12-07-2005|MM-dd-yyyy
3. Voi potete sempre farlo in modo più dettagliato in questo
modo
12-05-2005 00:00:00..12 -06-2005 23:59:59|MM -ddyyyy HH:mm:ss
80
Consiglio: Uso di campi DATE inv ece di campi DATETIME
Se avete bisogno di lavorare solo con le date allora si può
considerare di cambiare i campi datetime con solo campi date,
supponendo che il vostro db finale lo supporti. In tal caso Servoy
lavorerà in modo eccellente con questi campi , ma non sarà
necessario dire a Servoy ‘ignora la componente tempo ' poichè non
sarà necessario.
by Adrian McGilly , Servoy Consultant & Trainer
Copyright 2006, All Rights Reserved [TOP]
81
Spiegazione dei T abpanels
by Adrian McGilly
Panoramica sui Tabpanels
Una delle più potenti caratteristiche Gui in Servoy sono i tabpanels.
Un tabpanel è un'area rettangolare , su di una form, dove visualizzare
il contenuto di un’altra form o quello che alcuni chiamerebbero una
subform. Ci sono due modi nei quali i tabpanels vengono usati:
Visualizzazione di dati correlati
Potete mettere molte form nello stesso tabpanel e lasciare che
il vostro utente navighi su ognuno di essi . Di seguito
(circoscritto in rosso) c’è un esempio del suo uso nella
soluzione demo di CRM disponibile sul website di Servoy:
[TOP]
82
Ci sono quattro form in questo tabpanel, ciascuna accessibile
mediante un proprio tab, e ciascuno dei dati visualizzati è
correlato al record del cliente selezionato.
Visualizzare i Controlli di Navigazione
Potete usare il tabpanel anche come area di una form su cui
vengono mostrati tutti i pulsanti di controllo per navigare. Per
esempio, potete decidere di mettere lo stesso tipo di controllo
della navigazione su tutte le vostre form ma senza duplicare i
controlli su ognuna. Creereste solo una form contenente i
controlli di navigazione, e poi la mettete dentro un tabpanel su
ogni form che ha bisogno di gestire quei controlli.
Sotto (circoscritto in rosso) c’è l’esempio di un tabpanel usato
per mostrare i controlli di navigazione, della soluzione demo
CRM. Notate che non si deve guardare a lui come a un vero
tabpanel; perchè non ha i tabs e sui bordi esterni non c'è nulla
che riveli la presenza di forms separate al suo interno . Perché
un vero tabpanel mostra solo i tabs, ognuno dei quali
visualizza ogni form al suo interno . Potete fare in modo che il
tabpanel venga incorporato col resto delle form settando
opportunamente le proprietà dei suoi contorni .
83
Se avete messo diversi form in un tabpanel, si può scegliere di fare
usare all'utente questi tabs per navigare fra i subforms, ma anche di
poter programmare la navigazione fra i subforms. Se volete, voi
potete rimuovere i tabs e togliere così il controllo all'utente. Questo
è quello che noi chiamiamo un tabpanel del tabless.
Ciò che è straordinario dei tabpanels è che le forms inserite al loro
interno possono contenere delle funzionalità costruit e in loro (es.
bottoni per aggiungere, cancellare o andare sui records) e tutte
queste funzionalità continueranno a funzionare nel tabpanel. Per
esempio diciamo che create una form che deve contenere tutti i
controlli per gestire i contatti. Voi potete usarla come una form per
gestire standalone i contatti, e potete riusarla in un altro tabpanel
correlato alla form delle vostre Aziende clienti e disporre così di un
subform per gestire i contatti correlati a ciascuna Azienda.
84
Vi sono tre tipi di tabpanels di cui vogliamo parlare in questa
sezione:
• Related Tabpanels
• Relationless Tabpanels
• Tabless Tabpanels
Related Tabpanels
Forse l'uso più comune per i tabpanels è il tabpanel correlato.
Quando voi cliccate sul tool del tabpanel per creare un tabpanel
nuovo, Servoy vi chiede a quale relazione volete collegare il
subform. Vi presenterà solamente tutte le relazioni esistenti correlate
alla tabella sulla quale la vostra form corrente è collegata.
Quando cliccate su di una relazione dell'elenco, vi verranno
mostrate sulla destra della relazione, tutte le forms collegate ad essa
(ciò che chiamo 'destinazione' della relazione nel capitolo sulle
Relazioni in questo manuale.)
85
Una volta che scegliete una form da quell’elenco, quella form sarà
aggiunta al tabpanel. Sarà rappresentata con un tab all’interno del
corpo dell'oggetto tabpanel. Di sotto sono evidenziati i 4-tab
dell’oggetto tabpanel dell’esempio (soluzione demo CRM) visti in
ambiente di sviluppo.
86
Non dovete confondere le forms inserite nel tabpanel con i tabs
‘position example’ e 'position 2' in alto nel tabpanel. Essi sono in
quella posizione solo per illustrare dove i tabs dovranno apparire in
modalità run-time. In seguito, chiameremo i tabs che rappresentano
le vostre forms form-tabs.
Se cliccate una volta sulle form-tabs e guardate all’inizio del
pannello delle proprietà, vedrete il nome della relazione alla quale la
form-tab è collegata (oppure vedrete 'relationless ' se non è collegata
a nessuna relazione).
87
Se fate doppio-click su una form-tab in un oggetto tabpanel (in
design mode), Servoy vi porterà alla form rappresentata da quel
tab.La relazione a lla quale una form-tab è collegata determina il
foundset di records con il quale Servoy popoler à automaticamente il
subform quando la soluzione sta girando. Se la relazione per il
subform dei contatti è companies_to_contacts , allora ogni volta che
la subform viene visualizzata nel tabpanel, Servoy dovrà mostrare
tutti i records contatti correlati alla Azienda attualmente selezionata.
Leggere questa sezione per conoscere come aggiungere e rimuovere
le forms a (da) un oggetto tabpanel esistente.
Relationless Tabpanels
A volte la form inserita in un tabpanel non è la principale, o almeno
non coinvolta in una relazione. Questo può essere il caso per
esempio della subform che mostra i controlli della navigazione. In
questo caso, quando voi create il tabpanel e Servoy vi chiede a quale
88
relazione i subform dovranno essere collegati, fate un doppio-click
su 'Unrelated' e verrà mostrato un elenco di tabelle della vostra
soluzione, e sotto a ciascuna di esse, l'elenco di tutte le form
collegate. (Se il vostro subform contiene solo un gruppo di tasti di
navigazione e nessun dato, poi può sembrare strano che venga
chiesto di specificare la tabella della form in modo da arrivare alla
form stessa. Pensate semplicemente a questo come unico modo
fattibile che ha Servoy di organizzare le vostre form. Ricordate, ogni
form è collegata a una tabella, anche se non ne fà uso in alcun
modo.)
Tabless Tabpanels
Un mio studente una volta fece dei commenti relativi alla nozione
tabless tabpanel come nozione con tanto senso quanto quello di una
fetta di carne senza carne. Sia come sia, è ciò che ottenete quando
settate la proprietà tabOrientation di un tabpanel per nasconderlo.
Quando fate questo, porta te via il controllo dall'utente togliendo i
tabs dal tabpanel, e vi assumete la responsabilità di mostrare la
subform solo al momento giusto. Ulteriori spiegazioni su questo
tema nella sezione successiva.
Come si programmano i Tabs
Quando avete aggiunto molte form in un tabpanel, i vostri metodi
possono controllare che una di esse venga mostrata nel tabpanel
quando lo si decide. Una form con solo campi e bottoni in un
tabpanel è semplicemente un altro elemento sulla form. Una sua
proprietà è tabIndex. Se settato a 1, mostrerà la prima form. Se
messo a 2 mostrerà il secondo, e così via. Nella soluzione demo
CRM di Servoy con gli esempi illustrati sopra, la form principale è
stata chiamata companies, e il tabpanel è stato chiamato
tabs_bottom. Questo il comando per settare il tabpanel in modo che
mostri la seconda form, e s. la form che corrisponde al tab
'Addresses' :
forms.companies.tabs_bottom.tabIndex = 2
89
Voi potete controllare anche quale tab viene mostrata attualmente
con :
forms.companies.tabs_bottom.tabIndex
Aggiunta/cancellazione di form a/da un tabpanel
esistente
Per aggiungere un altra form a un tabpanel esistente avete bisogno
di selezionare prima l’oggetto tabpanel, cliccando sul tool del
tabpanel nella barra degli strumenti . Selezionando prima l’oggetto
tabpanel voi comunicate a Servoy di volere aggiungere una form a
un tabpanel esistente piuttosto che creare un nuovo oggetto tabpanel.
by Adrian McGilly , Servoy Consultant & Trainer
Copyright 2006, All Rights Reserved [TOP]
90
91
Le Relazioni
by Adrian McGilly
Panoramica sulle Relazioni
Le relazioni sono una delle caratteristiche più potenti e utili di
Servoy. Esse vi permettono di dare un nome riconoscibile a tutte le
relazioni fra i dati della soluzione, come ‘customers_to_orders’
oppure ‘orders_to_customers’. Dopo avere creato una relazione,
potete usarla in molti modi, ma i modi principali sono:
• ricerca records correlati
• creazione records correlati (con Se rvoy che si prende
automaticamente cura della integrità per voi)
• cancellazione records correlati
• conteggio del numero di records correlati
Chiavi Primarie & Chiavi Esterne
In qualsiasi relazione tra due tabelle, voi avete una chiave primaria
(PK) e una chiave esterna (FK). Considerate una relazione
customers-to-orders. Questa è una relazione ‘uno-a-molti’ con il
cliente come padre e gli ordini come figli. Ogni cliente ha una
colonna come chiave primaria che l'identifica univocamente. Ogni
record ordine deve avere una colonna che contiene la chiave
primaria del cliente al quale è collegato. Quella colonna viene
chiamata chiave esterna. In questo caso, la chiave esterna è un
puntatore da un record figlio a un record padre.
Origine & Destinazione: Un Modo di Pensare alle
Relazioni in Servoy
[TOP]
92
Una relazione può andare dal record padre verso i rispettivi records
figli, oppure dai records figli verso il padre, questo dipende dalle
proprie esigenze.
Il box di Definizione della Relazione vi chiede una chiave primari a
e una chiave esterna. La chiave primaria è a sinistra, e la chiave
esterna è a destra. L'unico problema per questo è che voi creerete
delle relazioni che vanno da un record a molti, e altre che vanno da
molti records a uno, ma nel secondo caso, la chiave sulla sinistra in
realtà sarà la chiave esterna, e la chiave sulla destra sarà la chiave
primaria che è l'opposto di ciò che il dialog di Definizione della
Relazione vi sta chiedendo.
Invece di pensare in termini di chiavi primarie e chiavi esterne,
preferisco pensare in termini di chiavi di record origine e
destinazione. Se volete una relazione che contiene gli ordini di un
cliente dovete andare dal rec cliente verso i suoi rec ordini. Se volete
una relazione che vi darà il cliente di un determinato ordine dovete
andare dall'ordine al cliente. La vostra origine ‘è ciò che voi già
avete’, la destinazione è ‘ciò di cui avete bisogno’. L’origine và
sulla sinistra, la destinazione va sulla destra. Fine della confusione.
Relazioni Uno-a-Molti
Se volete una relazione per ricercare, aggiungere, cancellare, contare
tutti gli ordini di un dato cliente, dovrete inserire:
93
Per default Servoy nomina questa relazione customers_to_orders
che collega fra loro le tabelle. Di solito non c’è il bisogno di
modificare il nome presentato per default , ma se volete potete farlo.
Potete fare uso di una delle caratteristiche più potenti di Servoy: il
tabpanel correlato. Potete creare un tabpanel per visualizzare /
modificare / aggiungere gli ordini collegati a un cliente. Quando
aggiungerete nuovi ordini in questo tabpanel Servoy si prender à
cura della integrità di tutti i dati che sono tra di loro collegati.
Per fare questo avete bisogno di una form (chiamiamola
ordersForm) collegata alla tabella ordini , che contenga quegli ordini
che volete mostrare nel vostro tabpanel (presumiamo per il
momento di stare trattando solo le testate dell'ordine e non le righe
dell'ordine). Una volta fatto, potete creare un tabpanel sulla form del
cliente, collegata alla relazione customers_to_orders, selezionate la
94
ordersForm e fatto! Ogni volta che l’utente seleziona un cliente sulla
form principale, Servoy automaticamente ricerca e mostra tutti gli
ordini del corrente cliente nel tabpanel.
Ora poniamo di inserire un tasto ‘Add’sul ordersForm il cui metodo
dice
controller.newRecord()
Se l'utente clicca su quel tasto Servoy saprà- perché sta usando la
form del tabpanel customers_to_orders -che si vuole creare un
nuovo record ordine che punti al (es. con la chiave esterna) PK del
corrente record cliente, e di conseguenza lo crea. Così come
spiegato nella sezione Lettura, Aggiunta & Cancellazione Records
Correlati è lo stesso che dire
customers_to_orders.newRecord().
Relazioni Molti-a-Uno
Al contrario, se volete una relazione che vi fornisca il cliente per un
dato ordine, dovrete inserire:
95
Per default Servoy nominerà la relazione orders_to_customers. Ora,
se voleste mostrare in un campo il cognome del cliente al quale
appartiene l'ordine selezionato, specifica te nella proprietà
dataprovider del campo:
orders_to_customers.last_name
Vedrete che l'IDE di Servoy vi farà accedere al momento giusto alla
giusta relazione. Ad esempio se aggiungete un nuovo campo alla
form Ordini (es. una form collegata agli ordini), il dialog che vi
lascia scegliere il dataprovider per il vostro campo lo farà
selezionare dalla relazione orders_to_customers e vi darà così
accesso al dataproviders del cliente correlato.
Relazioni Molti-a-Molti
Non è immediatamente facile comprendere come creare una
96
relazione molti-a-molti. Jan Aleman, CEO of Servoy, scrisse un
articolo su questo che potete vedere sul Periodico di Servoy:
http://www.servoymagazine.com/home/2004/10/article_nm_rela.
html
Relazioni nominate da voi
Potete definire voi stessi i nomi di relazione, per esempio riflettere
l’albero gerarchico degli impiegati e dei loro supervisori. Questa
relazione vuole ottenere tutti i consulenti che dipendono da un
consulente supervisore:
In questo caso sarebbe utile cambiare il nome della relazione con
qualche cosa di più significativo come consultants_to_reports .
Sappiamo che se decidete di cambiare il nome di una relazione,
questo comporta la rottura di tutti quei riferimenti già esistenti nel
vostro codice JavaScript. Questo non vale invece per tutti quei
97
luoghi dove la relazione viene usata, come ad esempio nella
proprietà ‘dataprovider’ del pan nello delle proprietà, oppure quando
viene specificata all’interno di un tabpanel, in tutti questi casi
Servoy 'rinomina' que lla relazione per voi.
Leggere questa sezione per informazioni sulle riparazioni ai metodi
che hanno subito il cambiamento al nome di un oggetto.
Relazioni Globali
Infine, potete creare relazioni globali, dove sul lato sinistro del nome
invece di un record c’è il nome di una var globale. Ciò può essere
utile in situazioni dove si devono recuperare records correlati, ma si
dispone solamente del valore della chiave PK del record padre, ma
non del percorso nel foundset. Di seguito vi è l’esempio di una
relazione che trova i progetti di un cliente la cui chiave PK è
contenuta in un campo globale globals.clientID:
98
Relazioni Nidificate
Si possono concatenare insieme delle relazioni per arrivare al
dataprovider correlato per un campo , come questo:
relation1.relation2.relation3.dataprovider
Per esempio, se da un record della tabella order_items volete
ottenere il cognome del cliente correlato, dovete fare così :
orderitems_to_orders.orders_to_customers.last_name
Se state scrivendo un metodo per una form collegata alla tabella
customer e desiderate inserire un campo co ntenente come
dataprovider un elemento orderitems 'HB1550' di un ordine, dovrete
dire:
customer_to_orders.orders_to_orderitems.part_no =
'HB1550'
Bene, ma quale record orderitems è riguardato da questo comando?
È 'la riga selezionata di un ordine seleziona to del cliente
selezionato'. E come facciamo a selezionare tutti questi records? Il
modo migliore per rispondere è di guardare a un esempio.
Diciamo che invece di assegnare l’elemento 'HB1550' di un ordine,
si vuole fare un loop su tutti gli ordini di un dato cliente per vedere
se il cliente abbia mai ordinato l’elemento #HB1550, si dovrebbe
fare:
/* configurazione di un for loop attraverso tutti i
records ordini del cliente corrente */
for (var n = 1; n <= customer_to_orders.getSize();
n++)
{
/* selezione del record orders dal
foundset o orders correlato*/
customer_to_orders.setSelectedIndex(o);
99
/* set up di un for loop attraverso tutti gli
elementi
dell’ordine selezionato */
for (var m = 1; m <=
customer_to_orders.orders_to_orderitems.getSize();
m++)
.
{
/* selezione de l record orderitems dal
foundset o orderitems correlato */
customer_to_orders.orders_to_orderitems.setSelectedIn
dex(m);
if
(customer_to_orders.orders_to_orderitems.part_no ==
'HB1550')
{
return true;
}
}
}
return false;
Lettura, aggiunta & ca ncellazione di record correlati
Guardiamo ad altri esempi di ciò che si può fare con le relazioni.
Questi esempi presumono di scrivere un metodo del form clienti
collegato alla tabella customer:
// seleziona tutti gli ordini correlati al cliente
scelto customers_to_orders.setSelectedIndex(n)
// aggiunge un nuovo record orders correlato al
customer scelto
customers_to_orders.newRecord()
/*aggiunge un nuovo record order_items al record
orders selezionato correlato al cliente selezionato
*/
customers_to_ orders.orders_to_orderitems.newRecord()
100
// cancella il record orders selezionato e correlato
al cliente scelto customers_to_orders.deleteRecord()
// vi dice quanti rec orders ci sono per quel cliente
selezionato customers_to_orders.getSize()
Riassumendo le Relazioni
Ricapitolando. Se volete una relazione che vada dal rec padre a ogni
rec figlio (es. parent_to_child), allora settate il box di Definizione
Relazioni così:
Parte sx
(source)
Parte dx
(destination)
Tabella
parent table
child table
Dataprovider
parent.pk
child.fk
Se volete una relazione che vada da ogni rec figlio a ogni rec padre
(es. parent_to_child), allora dovete fare:
Parte sx
(source)
Parte dx
(destination)
Tabella
child table
parent table
Dataprovider
child.fk
parent.pk
Opzioni di Relazione
Two options appear at the bottom of the relation dialog
• Permette la creazione dei records correlati
101
• Cancellazione dei records correlati
Di seguito la loro spiegazione
Permette la creazione dei records correlati
Nel nostro esempio di customers_to_orders, il comando
‘customers_to_orders.newRecord()’ crea un record ordine
correlato al record del cliente selezionato , ma solamente se
l’opzione corrispondente viene settata , altrimenti darà un
errore. Egualmente,
Cancellazione dei records correlati
Così come Servoy si prende cura della integrità dei riferimenti
quando si aggiungono records correlati tramite una relazione
(es. customers_to_orders.newRecord ()), così come assicura la
loro integrità quando si cancella un record padre. Se settata,
allora quando un metodo o un utente cancellano il record di
una tabella del lato sinistro della relazione, allora tutti i
records correlati della tabella nella parte destra della relazione
saranno cancellati. Questa è una scelta abbastanza potente –
che occorre usare con attenzione.
by Adrian McGilly , Servoy Consultant & Trainer
Copyright 2006, All Rights Reserved [TOP]
102
103
104
105
Consigli e Convenzioni sulla
Programmazione
by Adrian McGilly
Stabilire convenzioni sui nomi e attenersi a esse
Nella vostra codifica in Servoy si assegnano molte entità
diverse fra loro, all’interno dei:
forms (alcuni dei quali dovranno apparire solo nei tabpanels, e
nei subforms più che forms)
• dataproviders
• elements
• relations
• global vars
• local vars
• calcs
• global methods
• form methods
L’utilizzo di una convenzione sui nomi vi aiuterà nella vostra
organizzazione. Per esempio, se non siete accorti, si potrebbe
finire con l’avere un dataprovider chiamato last_name che
risiede in un campo chiamato last_name, e una var locale
chiamata last_name. Si otterrebbe cos ì una grande confusione.
Occorre anche sapere che tutti questi nomi sono cas e sensitive.
Non è la stessa cosa dire customerForm e CustomerForm. Così
non si possono usare i nomi mescolati, ma occorre mantenerli
uguali.
[TOP]
106
Una regola base per molti sviluppatori Servoy stà nell’usare
una distinzione, ad es. tra nomi di dataprovider e i nomi di
variabili usando tutte lettere minuscole e underscores ‘_’ per i
dataproviders (es. last_name) e quelle chiamate ‘camel case’
per le variabili (es. lastName o globals.lastName).
Ci sono dei buoni articoli scritti sulla convenzione dei nomi in
Servoy Magazine –questo è il link:
http://www.servoymagazine.com/home/2005/04/tip_organizatio
.html. Raccomando la lettura di questi articoli prima di
addentrarsi in qualsiasi soluzione che si intende distribuire e
manutenzionare.
Se si rinomina qualsiasi oggetto dopo averlo già adoperato nel
proprio codice, si compromettono i metodi che contengono i
vecchi riferimenti. Una sezione seguente spiega come si
possono riparare quei metodi che hanno subito la rinominazione
di oggetti.
Cliccare e non scrivere!
L' oggetto albero in Servoy Editor è molto in telligente nella
gestione degli errori di scrittura del codice. Quando fate doppio
click su una funzione o su una proprietà o dataprovider
nell'albero, questo muove il riferimento scelto nel vostro
codice. Ciò che non si può sapere prima è se il metodo ch e si
sta prelevando è un metodo di form o un metodo globale, e se è
un metodo della form, a quale form appartenga. Così ad
esempio, se lavorate in un metodo della form che appartiene
alla customerForm, e fate doppio-click su un dataprovider
chiamato last_name sotto il nodo del selectedRecord di quella
form, inserite last_name nel vostro metodo. Ma, se state
lavorando in un metodo globale (o un metodo che appartiene a
una diversa form), Servoy sa che vi deve proporre di inserire
precisamente nel vostro codice la stringa completa
‘forms.customerForm.last_name’ .
107
Per molte funzioni della libreria potete muovere una parte di
codice di esempio dentro il vostro metodo cliccando sul tasto
‘move sample’ nel Servoy Editor –questo vi fà risparmiare
molto tempo.
Quando muovete il vostro mouse su una proprietà o su una
funzione, la sua descrizione e sintassi appaiono brevemente con
un tooltip e inoltre appaiono anche nella sbarra di stato in basso
fino a quando muovete via il mouse .
Usare application.output() per vedere 'cosa sta
girando'
Quando si comincia a giocare con la scrittura dei metodi, si
troverà utile sbirciare i valori d i variabili, dataproviders e
valutare le espressioni al volo. Mentre il debugger offre un
buon aiuto in questa area, spesso trovo più utile ‘visualizzare’
queste cose sul pannello di output del debugger utilizzando
application.output() . Di seguito alcuni esempi:
Command
Output
(visibile nel pannello
output del debugger)
application.output('Hello
World')
Hello World
application.output('Hello' +
'World')
HelloWorld
application.output('last_name = '
+ last_name)
last_name = Smith
application.output('qty * price =
' + qty * price)
qty * price = 270
108
Dichiarazione di vars globali nella finestra
dataproviders
JavaScript permette di dichiarare var globali nei metodi, ma
queste non sono aggiunte automaticamente all'elenco di globals
nella finestra dataproviders. Cosa che potrebbe portare
disordine se si prolifica in dichiarazioni di var globali in tutto il
vostro codice, per cui è da evitare. Se le dichiarate tutte in un
metodo centrale dove si possono vedere tutte, sarebbe OK, ma è
preferibile dichiararle direttamente nella finestra dataproviders.
Usare Ctrl-spacebar per velocizzare la codifica
In codifica se si decide di scrivere piuttosto che cliccare, c'è
ancora un altro tool nel Servoy Editor che può aiutare, ed è il
comando control-barra spaziatura. Provare a scrivere ‘forms.’
in un metodo e poi premere control- barra spaziatura
(command-spacebar su Mac). Servoy presenta un elenco delle
form presenti nella vostra soluzione. Poi si può scegliere una
form col click del mouse o scorrendo la lista con la tastiera e
premendo il tasto invio. Servoy si muove al successivo livello
nell'oggetto albero e vi offre tutti i nodi sotto il nodo form. Farà
questo fino alla fine dell'albero.Buono!
Essere consapevoli del case-sensitivity
Ricordate che tutti i nomi di tutti gli oggetti, funzioni , metodi,
classi, dataproviders, tabelle, variabili ecc. sono case sensitive
in JavaScript. Una chiamat a al forms.customerForm.Validate()
non è la stessa del forms.CustomerForm.validate() e se non
siete accorti, potete passare molto tempo sul codice JavaScript
che genera errori di programmazione, e non vede re che il
problema può essere una semplice questione di una let tera
maiuscola, o viceversa.
Questa è un’altra buona ragione per cliccare invece di scrivere.
109
Settaggio delle proprietà a tempo di esecuzione
Si possono controllare dinamicamente molte proprietà della
vostra soluzione durante la sua esecuzione settandole
direttamente nei metodi. Ad esempio potete fare apparire i
campi, nasconderli, renderli modificabili o no, abilitare o
disabilitare intere form, ecc. Questo è spiegato nella
Developer’s User Guide.
Non tutte le proprietà che si vedono nel pannello delle proprietà
sono modificabili a tempo di esecuzione. Le proprietà che si
possono cambiare a programma per qualsiasi oggetto sono
elencate nel Servoy Editor ogni volta che si clicca su un
elemento dell' oggetto albero.
Quando cambiate in run-time una proprietà, la modifica persiste
solamente fino a quando l'utente chiude la soluzione, e poi
quella proprietà ritorna al suo stato originale. In ambiente di
sviluppo se uscite dal run-time mode e andate in design mode,
tutte le proprietà prima modificate sono riconvertite ai loro
valori originali.
Usare calcs non-memorizzati per checkboxes
Poniamo di voler presentare a un utente un elenco di records
clienti e lasciare che selezioni quello che vuole includere in un
processo (es. un report). Un modo sarebbe quello di mettere un
checkbox come campo del cliente e lasciare che l'utente scelga
quello che desidera. Come si fà questo?
Potete anche creare una colonna boolean nella tabella customer,
ma per questo occorre dedicare dello spazio su disco per una
colonna di cui non avete necessità di salvare, e inoltre dovete
preoccuparvi del flag quando viene salvato con lo stato in ‘on’.
Questo vi costringe a inizializzare sempre questi flags a false
prima di esporli come checkboxes.
La risposta è quella di creare un calc non memorizzato di tipo
110
integer nella tabella customer e settare nothing a ’all’, e con
solo il comando return nello script. Poi inserite nel calc il
dataprovider per il vostro checkbox e siete pronti per lavorare.
Quando il vostro utente seleziona un elemento del checkbox
nell'elenco (es. foundset) dei clienti, il calc per quella riga del
foundset sarà posto a 1. Per le righe non settate sarà posto a 0.
Inoltre conserverà il suo valore di 1 finchè il foundset rimane in
memoria. Se create un nuovo foundset, i calcs devono essere
tutti resettati a zero, e ciò consentirà a tutti i checkboxes
collegati al calc di risultare non selezionati.
Contenitori che non persistono alla uscita da
modalità run-time
In Servoy Deve loper, se si entra e si esce dalla modalità run time mentre siete in debug, ricordate che nessun dataproviders
o variabile globale, può persistere una volta che si esce da
modalità run-time. Questi oggetti ritornano al loro valore
originale che, a meno che non sia specificato diversamente, è
zero o vuoto (dipende dal tipo di var).
Fare spesso il Back up delle soluzioni
Ricordate, tutto il disegno delle vostre soluzioni e il lavoro di
programmazione è nel database servoy_repository.db. Se il
repository si corrompe o in qualche modo viene cancellato, voi
perdete tutte le soluzioni ivi contenute. Sebbene SQL
Anywhere sia molto stabile, è meglio non correre il rischio di
perdere tutto il vostro lavoro . Occorre fare frequenti backups
del vostro repository, e se possibile, della vostra intera cartella
database.
Uso dell’ help
L’ help presente sotto il menu di help è la stessa versione dello
stesso documento PDF di carta della guida di riferimento, solo
il tool di ricerca è diverso. Dopo avere compiuto una ricer ca
111
iniziale con il tab Ricerca per chiave, mostrerà un elenco
contenente le parole cercate. Per andare poi sulla pagina di un
tema specifico si deve selezionare Tools>> Find e cercare di
nuovo per chiave.
Global find & replace correzione dopo rinomina
oggetto
Se cambiate il nome di un oggetto che è referenziato nei vostri
metodi (es. una form, una relazione, un dataprovider ecc.) si
può compromette il loro funzionamento. Potete usare il
comando global find & replace che è sotto Edit>>Find
nell’Editor di Servoy per cercare le referenze al vecchio nome e
sostituirle col nuovo.
Tasti chiave per andare in Servoy Editor
Con Ctrl-Shift-M si ottiene di passare dalla finestra di design al
Servoy Editor. Questo, sia in design mode sia che la soluzione
stia girando.
Se volete modificare un metodo collegato a un evento nel
pannello delle proprietà, tenete premuto il tasto Ctrl con
doppio-click sul nome del metodo nel pannello della proprietà questo aprirà quel metodo in Servoy Editor.
Un altro consiglio, dopo aver fatto modifiche a un metodo,
premendo Ctrl-S il metodo verrà verificato e se non verrà
trovato alcun errore il metodo verrà salvato. Questo risulta più
rapido che fare i passi separati di verifica e salva.
by Adrian McGilly, Servoy Consultant & Trainer
Copyright 2006, All Rights Reserved [TOP]
Non dimenticare il doppio == nel comando if!
Ricordate che in JavaScript, per esaminare l’uguaglianza
bisogna usare due segni di uguale.
Non fate così:
112
if (i = j) /* assigns the value of j to i and
returns the value of i to your if test */
{…
}
ma così:
if (i == j) // uses two equal si gns to test if i
equals j
{…
}
Questo può essere un grave errore inserito nel
codice, annotate!
Selezionare righe di codice & formattarle in un colpo
Se volete formattare i margini di una parte di righe di codice in
un metodo, selezionate le righe che volete formattare e colpite il
tab – Servoy inserirà una tabulazione a fronte di ogni riga
selezionata.
Non c’è modo di chiedere all’editor una “particolare”
formattazione delle righe di codice con i rientri coerenti al
formato.
In Editor non usare alcune k eywords nei commenti
Nella versione 2.2.5 si possono generare alcuni errori quando si
tenta di salvare un metodo se vengono trovate parole riservate
JavaScript nei commenti. Se per esempio ottenete la
segnalazione ‘parola chiave function trovata in questo
script’potrebbe essere solo stato trovato ‘function’ in qualche
commento. (Sì, l’editor non digerisce la vista di parole riservate
inserite nei commenti). Voi dovrete trovare un modo diverso di
esprimerle. Esiste un elenco di parole riservate nell'Appendi ce
di Developer's Reference Guide.
Nella programmazione i Colori fanno stranezze
Servoy Editor quando codifica i colori nel vostro codice, non
113
sempre ottiene l’effetto giusto. Per esempio potrebbe inserire la
parola ‘for’ come un commento. Non prestate par ticolare
attenzione – è solo estetica e non riguarda le vostre funzionalità.
Lasciate Generare i Timestamps a Servoy
Avete bisogno di registrare il timestamp di creazione/modifica
per alcune tabelle? Servoy può farlo automaticamente. Occorre
creare due colonne per timestamps per la creazione e la
modifica del record e poi andare selezionare la colonna nella
finestra del dataproviders e cliccare sul tasto delle Proprietà.
Saranno mostrate le due proprietà di Creazione Timestamp e
Modifica Timestamp. Selezionare la proprietà corrispondente
ed è fatto!
by Adrian McGilly , Servoy Consultant & Trainer
Copyright 2006, All Rights Reserved [TOP]
114
Debugger Consigli e Suggerimenti
by Adrian McGilly
Servoy possiede un grande debugger. È documentato bene nella
Developer User’s Guide, ma qui ci sono un paio di consigli per chi
inizia:
La soluzione deve “girare” per poter fare uso del
debugger
Anche se può sembrare ovvio, lo dirò lo stesso. Non potete
fare girare un metodo o avanzare attraverso i suoi step se la
soluzione è in design mode. Se siete in ‘design’ mode allora
premete ctrl-L per comandare l’apertura della form corrente
in run-time, e quindi attivare il debugger.
Modifica dei metodi mentre la soluzione sta girando
Potete editare i metodi mentre la vostra soluzione è aperta in
'run-time'. L'unica eccezione che ho trovato è quando si ha il
debugger attivo e l’esecuzione è stata intercettata da un punto
d'arresto, allora non viene permessa nessuna editazione dei
metodi fino alla chiusura del debug, ad es. premendo il tasto
verde che completa l’esecuzione e chiude il debug.
Potete lanciare un metodo direttamente dal debugger
Colpendo il tasto verde ‘play’ si otterrà il lancio del metodo
attualmente mostrato. Questo è più veloce che predisporre un
tasto su una form per esaminare un metodo.
Visionare le variabili
In Servoy Editor il tab delle variabili serve solo per guardare
argomenti, vars locali e oggetti java. Non sono permesse
vars globali. Per le vars globali occorre usare il tab Wath.
Alcuni hanno avuto difficoltà nel capire l’uso di questi tab,
così spesso da fare uso del comando application.output () per
[TOP]
115
vedere il contenuto delle vars globali.
Il tab Evaluate serve per valutare espressioni al volo, oppure
per cambiare il valore di vars local i.
Pulire il pannello di output
Se il pannello del tab di Output appare pieno e si desidera
pulirlo, cliccare col tasto destro del mouse nel pannello che
vi presenterà la possibilità di pulirlo .
Comportamento del debbugger con showFormInDialog
Se state usando il debugger per avanzare all’interno di un
metodo che possiede un comando showFormInDialog,
otterrete uno strano comportamento del debugger quando vi
mostrerà il relativo box dialog . Se il comando
showFormInDialog() viene richiamato in un punto , allora il
sistema suppone uno stop di esecuzione de l metodo fino a
quando la finestra del dialog verrà CHIUSA. Se state
avanzando attraverso il metodo richiamato, rimarrà in quel
punto sospeso, e potrebbe procurarvi confusione. Se fate
debugger in un metodo con un showFormInDialog ()
richiamato, cercate di evitare di usare il tasto step e usate
invece use application.output() .
by Adrian McGilly, Servoy Consultant & Trainer
Copyright 2006, All Rights Reserved [TOP]
116
Appendice
by Adrian McGilly
Creazione di una Tabella con 500 record s
Questa sezione vi mostra il processo per inserire 500 records in una
nuova tabella con Servoy. Ciò è utile per imparare a navigare nei
foundsets, come discusso nella sezione sui foundsets.
1.
2.
Create un nuovo form chiamato FoundsetFun.
Quando presenta il dialog, chiamate il form
companiesForm e lo collegate al server database user_data, e a
una nuova tabella chiamata companies. Il dialog dovrebbe
essere:
[TOP]
117
3.
4.
5.
Premete OK. Questo vi porterà alla Finestra del
Dataproviders dove definirete le colonne per la tabella
companies. Per ora, abbiamo appena due colonne: la colonna
chiave primaria companiesid generata da Servoy, e la colonna
che voi aggiungerete chiamata name, di tipo testo e con
lunghezza 100. La finestra del Dataproviders dovrebbe essere
così:
Un click su Apply, e poi un click su OK.
Ora Servoy creer à la nuova form, e mostrerà un dialog
'Specify Field(s)' dove selezionare i campi da mostrare sulla
form. Selezionate entrambi i campi nell'elenco e settate 'Place
labels' nel checkbox. Il vostro dialog dovrebbe essere così :
118
6.
7.
Premete OK.
Ora andiamo in run-time mode con ctrl-L dovreste vedere
il controllo di navigazione sulla parte sinistra della finestra,
con zero record mostrati:
119
8.
Ora andiamo in Servoy Editor con Tools>> Editor.
Vedrete il companiesForm già selezionato nell'oggetto albero,
e nel pannello sotto l'albero un piccolo tasto verde per la
creazione di un nuovo metodo (vede re sotto). Cliccare sul
tasto per creare un nuovo metodo.
120
9.
Chiamare il metodo 'create500', e inserire il seguente
codice nel pannello di edit dei metodi:
for (var i = 1; i <=500; i++)
{
controller.newRecord();
name = 'Company ' + i;
}
Questo metodo crea 500 records nella tabella companies, e
ogni colonna name per ogni record sarà 'Company 1',
121
'Company 2', 'Company 3', etc.
10.
Il vostro metodo dovrebbe essere come illustrato sotto.
Ora cliccate sul tasto Verify per verificare e salvare il metodo,
e se non risultano errori, allora cliccate sul tasto verde "play"
per eseguire il metodo.
11.
Attendere mentre Servoy crea i 500 records nella tabella
companies. Ogni azienda sarà chiamata 'Company 1',
'Company 2', 'Company 3', ecc. Vi prenderà circa da 1 a 20
secondi a seconda della potenza della vostra macchina. Saprete
che ha finito quando tutti i tasti del debugger sono ritornati
allo stato inattivo come illustr ato sopra.
12.
Tornate al vostro form in run -time mode, e vedrete che ora
avete 500 records nella vostra tabella:
122
by Adrian McGilly , Servoy Consultant & Trainer
Copyright 2006, All Rights Reserved [TOP]
Questo documento è stato prodotto da Metamorfosi in proprio. La Casa Madre Servoy Consultant & Trainer che detiene i diritti sui documenti in lingua originale
non si assume alcuna responsabilità sui contenuti di questo documento nè di eventuali errori e omissioni.
Rev.
Data Rev.
Data 1°
Pubblicazione
Scritto da:
Prodotto da:
0
4/9/2006
4/9/2006
Michele Annese
Metamorfosi
123