Ri: Trattare con "In caso di cambiamento" all'interno di una classe in JSLIn realtà, il messaggio di errore che sto ricevendo è:
Nome irrisolto: clb in accesso o valutazione di 'clb', clb/*####*/
mi dispiace per quello!
Ri: Trattare con "In caso di modifica" all'interno di una classe in JSLPenso che i membri della classe abbiano a locale predefinito meccanismo, che tu lo voglia o no. In
method1 = Method({},
this:window = New Window( "Test Window", clb = Col List Box( all, On Change( Show( clb << Get Items ) ) ) );
);
clb viene assegnato quando method1 è in esecuzione, quindi dimenticato quando method1 restituisce. Molto più tardi, quando il metodo OnChange viene eseguito, non può essere trovato. Se vuoi una soluzione rapida e imperfetta, rendi clb più globale.
Una correzione migliore, ma più brutta, richiede l'incorporamento del valore di clb al posto di clb.
Define Class( "exampleClass",
// create the instance variables
m_clb = .;
m_window = .;
m_BC = .;
_init_ = Method( {},
m_BC = Open( "$SAMPLE_DATA/Big Class.jmp" );
m_window = Empty();
);
method1 = Method( {},
m_clb = Col List Box( all );
// add the on change script after creating the box. The script needs
// to reference the box. Substitute the actual box that m_clb refers
// to for the xxx placeholder name, then evaluate the resulting script
Eval( Substitute(
Expr( m_clb << onChange( Show( xxx << getselected ) ) ),
Expr( xxx ),
m_clb
));
m_window = New Window( "Test Window", m_clb );
);
);
// Create an object of the class and try to use the function
testObject = New Object( exampleClass() );
testObject:method1();
questo probabilmente non fa quello che ti aspetti. Non esiste un equivalente a C++ this-> e avrai difficoltà a inventarlo senza creare una perdita di memoria. Nell'esempio sopra, sarebbe ancora meglio incorporare questo piuttosto che clb, ma devi inventare un modo per ottenere questo .
Ho scritto due blog sulle classi, Come utilizzare Definisci classe e Programmazione funzionale tramite oggetti JSL . Ho provato a usare le lezioni diverse volte e non sono mai stato soddisfatto. Una cosa che una classe fa davvero bene è passare per riferimento, e questo potrebbe essere il motivo migliore per usarli. Il wrapping di un array di grandi dimensioni in un'istanza di classe rende possibile passare l'array alle funzioni scritte dall'utente senza eseguire una copia dell'array.
E se solo la richiamata < questo parametro, indicando la casella, questo sarebbe molto più semplice.
Ri: Trattare con "In caso di cambiamento" all'interno di una classe in JSL<< Set Function potrebbe essere una buona opzione da usare al posto di << On Change, poiché ha "this" come argomento della funzione. A seconda di cosa stai cercando di fare alla fine, direi che ci sono almeno tre diverse opzioni
1. Fai quello che suggerisce Craige e valuta il riferimento alla Col List Box
2. Usa << Set Function e quindi puoi fare riferimento a questo (che farà riferimento alla casella di riepilogo col stessa). Questi hanno comportamenti leggermente diversi ma potrebbero influire sulla tua applicazione
Define Class( "exampleClass",
m_clb = Empty();
m_window = .;
m_BC = .;
_init_ = Method( {},
m_BC = Open( "$SAMPLE_DATA/Big Class.jmp" );
m_window = Empty();
);
method1 = Method( {},
m_window = New Window("Test Window",
m_clb = Col List Box(
Datatable(m_BC),
all,
<< Set Function(function({this},
Show(this << get selected)
))
)
);
);
);
// Create an object of the class and try to use the function
testObject = New Object( exampleClass() );
testObject:method1();
3. Usa l'ambito della finestra ( Guida allo scripting > Metodi di programmazione > Scoping avanzato e spazi dei nomi > Nomi con ambito )
Define Class( "exampleClass",
m_window = .;
m_BC = .;
_init_ = Method( {},
m_BC = Open( "$SAMPLE_DATA/Big Class.jmp" );
m_window = Empty();
);
method1 = Method( {},
m_window = New Window("Test Window",
window:m_clb = Col List Box(
Datatable(m_BC),
all,
<< onChange(Show(window:m_clb << Get Selected))
)
);
);
);
// Create an object of the class and try to use the function
testObject = New Object( exampleClass() );
testObject:method1();Trattare con "On Change" all'interno di una classe in JSLCiao comunità!
Sono rimasto un po' bloccato durante l'utilizzo delle classi, quindi spero che qualcuno possa aiutarmi.
Un po' di contesto: sto lavorando su uno script che è diviso in due: uno script principale e uno script di funzioni, dove quest'ultimo è poi incluso nello script principale. Sto cercando di lavorare con classi e spazi dei nomi, per assicurarmi che le variabili vengano trovate solo quando dovrebbero essere trovate. Il mio problema specifico si verifica quando provo a utilizzare la funzione "On Change" con una casella di riepilogo colonne.
Ho fatto un esempio funzionante minimo che illustra il mio problema. Considera il codice principale:
Names Default To Here(1);
Clear log(); Clear Globals(); Clear Symbols();
// Include the class script
If( !Namespace Exists( "mainNamespace" ), New Namespace( "mainNamespace" ) );
mainNamespace:dir = Get Default Directory();
Include(mainNamespace:dir || "classScript.jsl");
// Create an object of the class and try to use the function
testObject = New Object( exampleClass());
testObject:method1();
e poi lo script di classe:
Names Default To Here(1);
If( !Namespace Exists( "classNamespace" ), New Namespace( "classNamespace" ) );
Define Class("exampleClass",
_init_ = Method( {},
this:BC = Open( "$SAMPLE_DATA/Big Class.jmp", Show(1) );
this:window = Empty();
);
method1 = Method({},
this:window = New Window( "Test Window", clb = Col List Box( all, On Change( Show( clb << Get Items ) ) ) );
);
);L'idea è di aprire una finestra in cui è possibile selezionare alcune colonne da una tabella di dati e quindi ottenere un elenco con le colonne selezionate. Funziona bene quando non uso le Classi, cioè se scrivo solo la parte delle classi dello script come codice "normale". Il codice sopra riesce ad aprire la tabella dei dati di Big Class e la finestra con la Col List Box, ma ogni volta che clicco su una colonna, ottengo un errore:
Send Expects Scriptable Object in accesso o valutazione di 'Send', clb << /*####*/Get Items /*####*/
C'è qualcosa che sto sbagliando o che non capisco? O ha qualcosa a che fare con la programmazione di "On Change"? Qualsiasi aiuto è apprezzato!
Accesso ai datiRe: Gestire "On Change" all'interno di una classe in JSLQuesto è un thread più vecchio, ma volevo pubblicare un'altra soluzione che ritengo sia molto utile quando si ha a che fare con le finestre all'interno delle classi. Simile alla soluzione di Jarmo, puoi utilizzare il messaggio << Imposta funzione, ma utilizzare una definizione di metodo. Ha approssimativamente la stessa funzionalità di una funzione con l'ulteriore vantaggio di valutare nell'ambito della classe, il che significa che è possibile fare riferimento a variabili oggetto.
Define Class( "exampleClass",
m_clb = Empty();
m_window = .;
m_BC = .;
_init_ = Method( {},
m_BC = Open( "$SAMPLE_DATA/Big Class.jmp" );
m_window = Empty();
);
method1 = Method( {},
m_window = New Window("Test Window",
m_clb = Col List Box(
Datatable(m_BC),
all,
<< Set Function(Method({this},
Show(this << get selected);
Show(m_clb << get selected);
Show(m_window);
Show(m_BC);
))
)
);
);
);
// Create an object of the class and try to use the function
testObject = New Object( exampleClass() );
testObject:method1();La variabile "this" funziona come spiegato da Jarmo, ma puoi anche fare riferimento a qualsiasi altra variabile della classe. Qui "questo" è equivalente a "m_clb".
Trovo che l'utilizzo dei metodi in questo modo sia molto comodo per creare finestre modulari con componenti interattivi.