Re: Umgang mit "On Change" innerhalb einer Klasse in JSLEigentlich bekomme ich folgende Fehlermeldung:
Name nicht aufgelöst: clb im Zugriff oder Auswertung von 'clb', clb/*###*/
Das tut mir leid!
Re: Umgang mit "On Change" innerhalb einer Klasse in JSLIch denke, die Klassenmitglieder haben a standardmäßig lokal Mechanismus, ob Sie es wollen oder nicht. In
method1 = Method({},
this:window = New Window( "Test Window", clb = Col List Box( all, On Change( Show( clb << Get Items ) ) ) );
);
clb wird zugewiesen, wenn Methode1 ausgeführt wird, und dann vergessen, wenn Methode1 zurückkehrt. Viel später, wenn die OnChange-Methode ausgeführt wird, kann sie nicht gefunden werden. Wenn Sie eine schnelle, unvollkommene Lösung wünschen, machen Sie clb globaler.
Eine bessere, aber hässlichere Lösung erfordert das Einbetten des Werts von clb anstelle von 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();
diese wahrscheinlich nicht das, was Sie erwarten. Es gibt kein Äquivalent zu einem C++ this-> und Sie werden es schwer haben, es zu erfinden, ohne ein Speicherleck zu erzeugen. Im obigen Beispiel wäre es noch besser einzubetten diese eher als clb, aber Sie müssen einen Weg erfinden, um es zu bekommen diese .
Ich habe zwei Blogs über Klassen geschrieben, So verwenden Sie Klasse definieren und Funktionale Programmierung mit JSL-Objekten . Ich habe mehrmals versucht, Klassen zu verwenden, und war nie zufrieden. Eine Sache, die eine Klasse wirklich gut kann, ist das Übergeben von Referenzen, und das ist möglicherweise der beste Grund, sie zu verwenden. Das Einschließen eines großen Arrays in eine Klasseninstanz ermöglicht es, das Array an vom Benutzer geschriebene Funktionen zu übergeben, ohne eine Kopie des Arrays zu erstellen.
Und wenn nur der < diese Parameter, der auf die Box zeigt, wäre dies so viel einfacher.
Re: Umgang mit "On Change" innerhalb einer Klasse in JSL<< Set Function könnte eine gute Option sein, die anstelle von << On Change verwendet werden kann, da es "this" als Funktionsargument hat. Je nachdem, was Sie am Ende versuchen zu tun, würde ich sagen, dass es mindestens drei verschiedene Optionen gibt
1. Tun Sie, was Craige vorschlägt, und werten Sie den Verweis auf die Col List Box aus
2. Verwenden Sie << Set Function und dann können Sie darauf verweisen (was sich auf das Listenfeld col selbst bezieht). Diese haben ein etwas anderes Verhalten, aber es kann sich auf Ihre Anwendung auswirken
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. Fensterbereich verwenden ( Skriptleitfaden > Programmiermethoden > Erweitertes Scoping und Namespaces > Scoped Names )
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();Umgang mit „On Change“ innerhalb einer Klasse in JSLHallo Community!
Ich bin bei der Verwendung von Klassen etwas hängen geblieben und hoffe, dass mir jemand helfen kann.
Ein bisschen Kontext: Ich arbeite an einem Skript, das in zwei Teile unterteilt ist: ein Hauptskript und ein Funktionsskript, wobei letzteres dann in das Hauptskript eingebunden wird. Ich versuche, mit Klassen und Namespaces zu arbeiten, um sicherzustellen, dass Variablen nur dann gefunden werden, wenn sie gefunden werden sollen. Mein spezielles Problem tritt auf, wenn ich versuche, die Funktion „Bei Änderung“ mit einem Col-List-Feld zu verwenden.
Ich habe ein minimales Arbeitsbeispiel erstellt, das mein Problem veranschaulicht. Betrachten Sie den Hauptcode:
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();
und dann das Klassenskript:
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 ) ) ) );
);
);Die Idee besteht darin, ein Fenster zu öffnen, in dem Sie einige Spalten aus einer Datentabelle auswählen und dann eine Liste mit den ausgewählten Spalten erhalten können. Das funktioniert gut, wenn ich keine Klassen verwende, dh wenn ich nur den Klassenteil des Skripts als „normalen“ Code schreibe. Der obige Code schafft es, die Big-Class-Datentabelle und das Fenster mit dem Col-List-Feld zu öffnen, aber jedes Mal, wenn ich auf eine Spalte klicke, erhalte ich eine Fehlermeldung:
Send erwartet ein skriptfähiges Objekt beim Zugriff oder bei der Auswertung von „Send“, clb << /*###*/Get Items /*###*/
Mache ich etwas falsch oder verstehe ich es nicht? Oder hat es etwas damit zu tun, wie „On Change“ programmiert ist? Jede Hilfe ist willkommen!
DatenzugriffBetreff: Umgang mit „On Change“ innerhalb einer Klasse in JSLDies ist ein älterer Thread, aber ich wollte eine weitere Lösung posten, die meiner Meinung nach sehr praktisch ist, wenn man mit Fenstern innerhalb von Klassen umgeht. Ähnlich wie bei Jarmos Lösung können Sie die Nachricht << Set Function verwenden, aber eine Methodendefinition verwenden. Sie hat ungefähr die gleiche Funktionalität wie eine Funktion, bietet aber zusätzlich den Vorteil, dass sie innerhalb des Gültigkeitsbereichs der Klasse auswertet, was bedeutet, dass Sie auf Objektvariablen verweisen können.
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();Die Variable „this“ funktioniert genauso wie Jarmo erklärt hat, aber Sie können auch auf jede andere Variable aus der Klasse verweisen. Hier entspricht „this“ „m_clb“.
Ich finde, dass die Verwendung von Methoden auf diese Weise sehr praktisch ist, um modulare Fenster mit interaktiven Komponenten zu erstellen.