How to reference one element of an array property from another class
Hello,
I need to add a new property ("Injection") to an existing database. The existing database contains, in part:
An "ImageStudy" which contains one or more "ImageFiles" defined as follows:
Class PET.ImageStudy Extends (%Persistent)
{
Relationship ImageFiles as PET.ImageFile [cardinality=children,inverse=Study]
...
}
Class PET.ImageFile Extends (%Persistent)
Relationship Study as PET.ImageStudy [cardinality=parent,inverse=ImagFiles]
...
}The requirements for the Injection are that 1)an ImageStudy can have one or more Injections; 2)an ImageFile is associated with a single Injection; 3)More than one ImageFile can be associated with a single Injection; 4)the Injection does not need to be persistent, it can be embedded in the ImageStudy. I am planning to define the Injection as a %SerialObject containing RadioTracer, Dose and Time properties, and then include the Injection in the ImageStudy Class as
Property Injection As array of Injection;My questions are
1) Is this a good way to define the Injection property?
2)What is the best way to associate the ImageFile with a single Injection? Would I just add a property to the ImageFile to store the array key for the associated Injection?
Thanks and apologies for the extremely elementary questions -- I have very little experience with databases.
Comments
Hi,
You can create Injection as a %SerialObject and add to Study as a list
`` `
Property Injection As list Of PET.Injection;
```
OK, thanks.
Is there a good reason to define the Injection property as a list, rather than an array, as I had been planning?
In either case, how do I associate a single element of the Injection property with an ImageFile (ie, should I just store the array key as a property in the ImageFile, or is there a better mechanism)?
Wow, thank you! I will try this!
Sorry for delay...
You can use both, as a list you will use the insert method like a relationship
Set inj = ##class(PET.Injection).%New(), inj.Desc = "blabla "_i
Do study.Injection.Insert(inj)
It will add a column with the list
You can use an array, but you must use SetAt:
Do study.InjectionArr.SetAt(inj,i)
And it will create another table with the name of the property
OK, thanks!
So then if I store the Injection element_key (in the case of an array), as a property in the ImageFile object which references the injection, I will be able to get to the various Injection properties from the ImageFile instance?
What would I store in the ImageFile in the case of a list?
Thanks for your help!
"So then if I store the Injection element_key (in the case of an array), as a property in the ImageFile object which references the injection, I will be able to get to the various Injection properties from the ImageFile instance? "
Sure, just to pay attention to manage the array key, that will be like your ID
"What would I store in the ImageFile in the case of a list? "
You can use list like a collection, could be of %SerialObjects or other types like %Strings, in the table will be save like $Piece in the column
Something to play with:
===========================================================================================
Class PET.ImageStudy Extends (%Persistent, %ZEN.DataModel.Adaptor) [ Inheritance = right ]
{
Property Code As %String [ Required ];
Property Name As %String [ Required ];
Relationship ImageFiles As PET.ImageFile [ Cardinality = children, Inverse = Study ];
-------------------------------------------------------------------------------------------------------------------------------------------------
Class PET.ImageFile Extends (%Persistent, %ZEN.DataModel.Adaptor) [ Inheritance = right ]
{
Property Code1 As %String [ Required ];
Property Name1 As %String [ Required ];
Property Image As %Stream.FileBinary;
Property Path As %String(MAXLEN = 100);
Relationship Study As PET.ImageStudy [ Cardinality = parent, Inverse = ImageFiles ];
--------------------------------------------------------------------------------------------------------------------------------------------------
Class PET.TestA Extends %ZEN.Component.page
{
Parameter APPLICATION;
Parameter PAGENAME;
Parameter DOMAIN;
XData Style
{
<style type="text/css">
</style>
}
XData Contents [ XMLNamespace = "http://www.intersystems.com/zen" ]
{
<page xmlns="http://www.intersystems.com/zen" title="" >
<hgroup valign="top">
<pane paneName="Study" />
<pane paneName="Image" />
</hgroup>
</page>
}
XData Study [ XMLNamespace = "http://www.intersystems.com/zen" ]
{
<pane xmlns="http://www.intersystems.com/zen" title="" align="left" width="400" valign="top">
<fieldSet legend="Study">
<dataController modelId="" id="ctrlParent" modelClass="PET.ImageStudy"/>
<form id="frmId" controllerId="ctrlParent" labelPosition="left">
<tableNavigatorBar showPageSize="true" id="nav" tablePaneId="table" />
<vgroup valign="top">
<tablePane width="400px" id="table"
tableName="PET.ImageStudy"
maxRows="1000" pageSize="5"
showZebra="true" useSnapshot="true"
valueColumn="ID"
onselectrow="zenPage.rowSelected(zenThis,which);">
<column colName="ID" hidden="true"/>
<column header="Code" colName="Code" width="30%" />
<column header="Name" colName="Name" width="70%" />
</tablePane>
</vgroup> <spacer width="15px"/>
<vgroup valign="top">
<text label="Code:" id="Code" name="Code" dataBinding="Code" size="15" required="true"/>
<text label="Name:" id="Name" name="Name" dataBinding="Name" size="30" required="true"/>
<spacer height="10"/>
<hgroup>
<button caption="New" onclick="zenPage.newRecord();" />
<button caption="Save" onclick="zenPage.saveRecord();" />
<button caption="Cancel" onclick="zenPage.cancelRecord();" />
<button caption="Delete" onclick="zenPage.deleteRecord();" />
</hgroup>
</vgroup>
</form>
</fieldSet>
</pane>
}
XData Image [ XMLNamespace = "http://www.intersystems.com/zen" ]
{
<pane xmlns="http://www.intersystems.com/zen" title="" valign="top" >
<fieldSet legend="FileImage">
<dataController id="ctrlChildren1" modelClass="PET.ImageFile" modelId=""/>
<form id="frmIdChild1" controllerId="ctrlChildren1" labelPosition="left">
<tableNavigatorBar showPageSize="true" id="nav1" tablePaneId="Table1" />
<hgroup>
<vgroup valign="top">
<tablePane width="400px" id="Table1"
tableName="PET.ImageFile"
whereClause="Study=?"
maxRows="1000" pageSize="5" showZebra="true"
useSnapshot="true"
valueColumn="ID"
onselectrow="zenPage.rowSelectedChild1(zenThis);">
<column colName="ID" hidden="true"/>
<column header="Code" colName="Code1" width="10%" />
<column header="Name" colName="Name1" width="20%"/>
<column colName="Path" header="Path" width="25%" hidden="true"/>
<column colName="Image" header="Image" width="45%" OnDrawCell="DrawCell"/>
<parameter value="zen('ctrlParent').getProperty('modelId');"/>
</tablePane>
</vgroup>
<spacer height="15px"/> <spacer width="15px"/>
<vgroup>
<text label="Id:" id="Id" name="Id" readOnly="true" dataBinding="%id" hidden="true"/>
<text label="Code:" id="Code1" name="Code1" dataBinding="Code1" size="15" required="true"/>
<text label="Name:" id="Name1" name="Name1" dataBinding="Name1" size="30" required="true"/>
<text label="File name:" id="Path" name="Path" dataBinding="Path" size="60" />
<button id="buttonF" caption="Browse" onclick="zenPage.fileSelect();"/>
<spacer height="10"/>
<image id="image" width="100" height="100"/>
<spacer height="10px"/>
<hgroup>
<button caption="New" onclick="zenPage.newChildRecord1();" />
<button caption="Save" onclick="zenPage.saveChildRecord1();" />
<button caption="Cancel" onclick="zenPage.cancelChildRecord1();" />
<button caption="Delete" onclick="zenPage.deleteChildRecord1();" />
</hgroup>
</vgroup>
</hgroup>
</form>
</fieldSet>
</pane>
}
Method DrawCell(pTable As %ZEN.Component.tablePane, pName As %String, pSeed As %String) As %Status
{
Set id=%query("ID")
Set obj=##class(PET.ImageFile).%OpenId(id)
If (obj) {
s filename=%query("Path")
Set stream=##class(%FileBinaryStream).%New()
Do stream.LinkToFile(filename)
Set oid=stream.%Oid()
&html<<image src="%25CSP.StreamServer.cls?STREAMOID=#(..Encrypt(oid))#">>
}
Quit $$$OK
}
Method Image(id As %String) As %Status [ ZenMethod ]
{
set img=..%GetComponentById("image")
Set obj=##class(PET.ImageFile).%OpenId(id)
If (obj) {
s filename=obj.Path
s filename=$tr(filename,"\","/")
Set stream=##class(%FileBinaryStream).%New()
Do stream.LinkToFile(filename)
Set oid=stream.%Oid()
set img.streamId=oid
}
Quit $$$OK
}
Method ShowImage(id As %String, filename As %String) As %Status [ ZenMethod ]
{
set img=..%GetComponentById("image")
s filename=$tr(filename,"\","/")
Set stream=##class(%FileBinaryStream).%New()
Do stream.LinkToFile(filename)
set img.streamId=stream.%Oid()
Quit $$$OK
}
ClientMethod fileSelect() [ Language = javascript ]
{
var Dir='c:/InterSystems/TryCache/csp/broker/';
var wildcard='';
zenLaunchPopupWindow('%ZEN.Dialog.fileSelect.cls?Dir='+encodeURIComponent(Dir)+'&wildcard='+wildcard,'FileSelect','resizable,width=600,height=700');
}
ClientMethod onPopupAction(popupName, action, value) [ Language = javascript ]
{
switch(popupName){
case 'FileSelect':
if (action == "ok") {
var id = zen('Table1').getValue();
zen('ctrlChildren1').setDataByName('Path',value);
zen("Path").setValue(value);
var x=this.ShowImage(id,value);
zen('image').refreshContents();
}
}
}
ClientMethod resetTable1() [ Language = javascript ]
{
var table1 = zen('Table1');
table1.setProperty('initialExecute',false);
table1.executeQuery(true);
zen('frmIdChild1').reset();
}
ClientMethod rowSelected(table, which) [ Language = javascript ]
{
var controller = zen('ctrlParent');
if (controller.getModelId()==table.getValue()) { return; }
else{
if (('keypress' == which)||(zenRefreshMode==1)) {
// defer this action in case the user is arrowing through aCode of items
var id = table.getValue();
var action = new Function("zen('ctrlParent').setProperty('modelId','"+id+"' );");
zenSetDeferredAction(action,200);
}
else {
var id = table.getValue();
controller.setProperty('modelId',id);
// Update the child section
var Table1 = zen('Table1');
Table1.setProperty('parameters',1,id);
Table1.selectRow(-1);
zen('frmIdChild1').reset();
}
}
}
ClientMethod rowSelectedChild1(table1, which) [ Language = javascript ]
{
var controller1 = zen('ctrlChildren1');
if (controller1.getModelId()==table1.getValue()) { return; }
else {
if (('keypress' == which)||(zenRefreshMode==1)) {
// defer this action in case the user is arrowing through a Code of items
var childid1 = table1.getValue();
var action = new Function("zen('ctrlChildren1').setProperty('modelId','"+childid1+"' );");
zenSetDeferredAction(action,200);
}
else {
var childid1 = table1.getValue();
controller1.setProperty("modelId",childid1);
var x=this.Image(childid1);
zen('image').refreshContents();
}
}
}
ClientMethod newRecord() [ Language = javascript ]
{
this.resetTable1();
zen('ctrlParent').setProperty('modelId','');
}
ClientMethod newChildRecord1() [ Language = javascript ]
{
var controller = zen('ctrlParent');
var id = controller.getModelId();
if ('' == id) {alert('Nothing selected!'+'\n'+'Please select row in Parent table!');}
else {zen('ctrlChildren1').setProperty('modelId','');}
}
ClientMethod saveRecord() [ Language = javascript ]
{
zen('frmId').save();
zen('table').executeQuery(true);
zen('ctrlParent').setProperty('modelId','');
this.resetTable1();
}
ClientMethod saveChildRecord1() [ Language = javascript ]
{
var controller = zen('ctrlParent');
var id = controller.getModelId();
if ('' == id) {alert('Nothing selected!'+'\n'+'Please select row in Parent table!');}
else {
zen('ctrlChildren1').setDataByName('Study',zen('ctrlParent').getProperty('modelId'));
zen('frmIdChild1').save();
zen('Table1').executeQuery(true);
zen('ctrlChildren1').setProperty('modelId','');
zen('Table1').selectRow(-1);
zen('frmIdChild1').reset();
}
}
/// cancel the current action
ClientMethod cancelRecord() [ Language = javascript ]
{
zen('table').selectRow(-1);
zen('frmId').reset();
var table1 = zen('Table1');
table1.setProperty('initialExecute',true);
zen('Table1').selectRow(-1);
}
ClientMethod cancelChildRecord1() [ Language = javascript ]
{
zen('Table1').selectRow(-1);
zen('frmIdChild1').reset();
}
/// Delete current item from database
ClientMethod deleteRecord() [ Language = javascript ]
{
var controller = zen('ctrlParent');
var id = controller.getModelId();
if ('' == id) {alert('Nothing selected.');}
else if (confirm('Are you sure you want to delete the record?')){
controller.deleteId(id);
zen('frmId').reset();
zen('table').executeQuery(true);
this.resetTable1();
}
}
/// Delete current item from database
ClientMethod deleteChildRecord1() [ Language = javascript ]
{
var controller1 = zen('ctrlChildren1');
var childid1 = controller1.getModelId();
if ('' == childid1) {alert('Nothing selected.');}
else if (confirm('Are you sure you want to delete the record?')){
controller1.deleteId(childid1);
zen('frmIdChild1').reset();
zen('Table1').executeQuery(true);
}
}
}
=======================================================================================================