Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Datasources cause a problem when loading same screen twice. Unclear when to use loadID

    Hello,

    we are currently working to update to V14.1-p20260213/Power.
    We are using ui.xmls and ds.xmls to create the uis of our app. In most cases this works even after the update.
    To load the screens we use the RPCManager.loadScreen method with the allGlobals flag.

    In the following description I have replaced all internal data but the important parts should all be available.

    Now for my problem. We have a button which should create a window in which a few datasources are needed.
    For that window an ui.xml exists.
    For the first call this works. But after closing the window and pressing the button again which should create a new window I can't create it because of the datasources.
    In the developer console this error appears:

    Click image for larger version

Name:	StacktraceForUnexpectedToken.png
Views:	74
Size:	28.4 KB
ID:	277554

    This Syntax error comes from the answer of the screenLoader which returns:



    [
    ]
    [
    ]
    [
    ]
    [
    ]
    [
    ]

    isc.ListGrid.create({
    ID:"DIALOG_ListGrid",
    autoDraw:false,
    autoFetchData:false,
    dataSource:"datasource1",
    height:"100%",
    fields:[
    {
    align:"left",
    name:"NAME",
    title:"title",
    width:80,
    showIf:"true",
    optionDataSource:"datasource2",
    valueField:"PLC",
    displayField:"PLC",
    canEdit:true,
    autoFetchDisplayMap:true,
    multiple:true
    }
    ],
    autoSaveEdits:false,
    showFilterEditor:true,
    filterOnKeypress:true,
    canEdit:false,
    groupByMaxRecords:1000,
    fetchDelay:1000,
    allowFilterExpressions:true,
    canMultiSort:"true",
    sortField:"PLC",
    canMultiGroup:"true",
    groupStartOpen:"none",
    selectionType:"simple",
    selectionAppearance:"checkbox"
    })


    isc.DynamicForm.create({
    ID:"DIALOG_DynamicFormLeft",
    autoDraw:false,
    width:"30%",
    fields:[
    {
    name:"Display",
    value:"Display",
    _constructor:"HeaderItem"
    },
    {
    name:"NAME",
    rowSpan:0,
    title:"Title",
    width:"100%",
    _constructor:"CheckboxItem"
    }
    ],
    layoutAlign:"center",
    titleWidth:12
    })


    isc.DynamicForm.create({
    ID:"DIALOG_DynamicFormRight",
    autoDraw:false,
    width:"70%",
    fields:[
    {
    name:"Name",
    value:"value",
    _constructor:"HeaderItem"
    },
    {
    name:"MessageTypeSelectItem",
    showTitle:false,
    multiple:true,
    optionDataSource:"datasource5",
    valueField:"MESSAGETYPE",
    displayField:"MESSAGETYPE",
    autoFetchDisplayMap:"true",
    _constructor:"SelectItem"
    }
    ],
    layoutAlign:"center",
    titleWidth:12
    })


    isc.VLayout.create({
    ID:"DIALOG_DynamicForm_VLayoutDynamicFormRight",
    autoDraw:false,
    height:"100%",
    members:[
    DIALOG_DynamicFormRight
    ]
    })


    isc.HLayout.create({
    ID:"DIALOG_DynamicForm_Layout",
    autoDraw:false,
    members:[
    DIALOG_DynamicFormLeft,
    DIALOG_DynamicForm_VLayoutDynamicFormRight
    ]
    })


    isc.IButton.create({
    ID:"DIALOG_Select_All",
    autoDraw:false,
    height:36,
    width:36,
    icon:"/icon/ic_set_unset_check_2.svg",
    iconSize:27,
    prompt:"Select all (Can be used for 75 rows or less)"
    })



    isc.IButton.create({
    ID:"DIALOG_ResetFilter",
    autoDraw:false,
    height:36,
    width:36,
    icon:"/icon/ic_reset.svg",
    iconSize:27,
    prompt:"Reset filter"
    })


    isc.HLayout.create({
    ID:"DIALOG_ToolBar",
    autoDraw:false,
    height:56,
    members:[
    DIALOG_Select_All,
    DIALOG_ResetFilter
    ],
    layoutMargin:12,
    membersMargin:12,
    backgroundColor:"#F2F2F2"
    })


    isc.Label.create({
    ID:"DIALOG_ListGridTitle",
    autoDraw:false,
    height:20,
    contents:"Device Selection",
    styleName:"titleText"
    })


    isc.VLayout.create({
    ID:"DIALOG_MAIN_Layout",
    autoDraw:false,
    members:[
    DIALOG_DynamicForm_Layout,
    DIALOG_ListGridTitle,
    {
    autoDraw:false,
    height:3,
    _constructor:"LayoutSpacer"
    },
    DIALOG_ListGrid,
    DIALOG_ToolBar
    ],
    layoutMargin:20
    })


    isc.IButton.create({
    ID:"DIALOG_Ok",
    autoDraw:false,
    height:36,
    icon:"/icon/ic_confirm.svg",
    iconSize:27,
    prompt:"Ok",
    visibility:"inherit"
    })


    isc.IButton.create({
    ID:"DIALOG_Cancel",
    autoDraw:false,
    height:36,
    icon:"/icon/ic_cancel.svg",
    iconSize:27,
    prompt:"Cancel",
    visibility:"inherit"
    })


    isc.HLayout.create({
    ID:"DIALOG_ButtonLayout",
    autoDraw:false,
    height:48,
    width:"100%",
    align:"center",
    members:[
    DIALOG_Ok,
    DIALOG_Cancel
    ],
    layoutMargin:12,
    membersMargin:12
    })


    isc.Window.create({
    ID:"DIALOG",
    autoDraw:false,
    height:"90%",
    overflow:"auto",
    width:850,
    autoCenter:true,
    isModal:true,
    autoSize:false,
    title:"title",
    showMinimizeButton:false,
    showMaximizeButton:true,
    showFooter:false,
    items:[
    DIALOG_MAIN_Layout,
    DIALOG_ButtonLayout
    ],
    showModalMask:true
    })

    -------------------------------------------------------------------------------------------------------------------------------------------------
    In our ui.xml we have multiple datasources defined like this:


    <DataSource ID="datasource2"/>
    <DataSource ID="datasource3"/>
    <DataSource ID="datasource4"/>
    <DataSource ID="datasource5"/>
    <DataSource>
    <loadID>datasource1</loadID>
    </DataSource>

    and any other configuration doesn't work. If I use loadID for the other datasources or the ID for datasource1 it throws the errors above when I open the window a second time.
    The datasources are not special in any way. This is our reduced datasource1 so no internal data is shown:

    <?xml version="1.0" encoding="UTF-8"?>
    <DataSource
    ID="datasource1"
    autoDeriveSchema="false"
    serverType="sql"
    tableName="TABLE"
    requiresRole="ROLE">
    <fields>
    <field name="NAME" tableName="TABLE" type="text"/>
    </fields>
    <operationBindings>
    <operationBinding operationType="fetch">
    <selectClause>DISTINCT $defaultSelectClause</selectClause>
    <tableClause>TABLE LEFT JOIN OTHER_TABLE ON TABLE.field = OTHER_TABLE.field
    </tableClause>
    <whereClause>($defaultWhereClause)</whereClause>
    </operationBinding>
    </operationBindings>
    </DataSource>



    To compare, this is our reduced datasource2:

    <?xml version="1.0" encoding="UTF-8"?>
    <DataSource
    ID="datasource2"
    autoDeriveSchema="false"
    serverType="sql"
    tableName="TABLE3"
    requiresRole="ROLE">
    >
    <fields>
    <field name="FIELD" type="text"/>
    </fields>
    <operationBindings>
    <operationBinding operationType="fetch">
    <selectClause>DISTINCT TABLE.FIELD</selectClause>
    <orderClause>FIELD ASC</orderClause>
    </operationBinding>
    </operationBindings>
    </DataSource>



    Now I want to know when I have to use loadID and when the ID or if there is a setting so we don't have to change all of our ui.xmls as we have used the pattern with loadID everywhere in our project. Unfortunately I found nearly nothing to loadID in the docu or in the forum. I only found a bugfix in the release notes for GWT3.1 and this forum post from 2017 which says loadID is correct https://forums.smartclient.com/forum...xml#post249706

    #2
    How did you end up with this component XML in your .ui.xml file?
    Code:
    <DataSource ID="datasource2"/>
    <DataSource ID="datasource3"/>
    <DataSource ID="datasource4"/>
    <DataSource ID="datasource5"/>
    <DataSource>
    <loadID>datasource1</loadID>
    </DataSource>
    That's not documented as supported in SmartGWT component XML. The documented approach would be to skip the <DataSource/> declarations completely and use DataSourceLoader to pre-load the required DataSources.

    Comment


      #3
      Sorry for the long wait. This is in a project I was not part of since the beginning and the person responsible was on a vacation.
      The reason we have it in the ui.xml is because it was possible before and we wanted it easy for people to create screens.
      I don't think there is any documentation left for a more detailed explanation.

      So for our support and project team as well as for our customers all they had to do was to create a ui.xml and they could see the data they wanted. But now we have to experiment when we have to use loadID and when to use the normal ID and we haven't found a pattern that explains their differences.

      Comment


        #4
        We definitely would not recommend "experimenting" since, as far as we can tell, that's how you ended up with random content in your .ui.xml file that did nothing in the past, but now causes a syntax error. That's a classic case of trying random, unsupported stuff and having it cause pain in the future!

        Here's the upshot:

        1) generally, when using .ui.xml files, you cause the DataSources to be loaded before you load the .ui.xml file (typically via DataSourceLoader)

        There is no mechanism to load them in the .ui.xml file, because that doesn't make sense: DataSources are typically shared across many .ui.xml files, so loading them in every .ui.xml file would be a mistake.

        All you do in the .ui.xml file is provide <dataSource>dsId<dataSource> declarations inside of component definitions, such as within a <ListGrid> tag. These are, and have always been, supported. They do not, and have never, cause DataSources to be loaded.


        2) there is a newer mechanism you might way to switch to - Projects and .proj files - which allow loading multiple .ui.xml files at once, and where the project can declare the DataSources it needs

        The mechanism - loadProject() - will load declared DataSources as needed, without loading duplicates (it checks what's already loaded and provides that info to the server).

        You may want to switch to this - it's all doc'd - but probably all you really need to do is clean up the crud in your older .ui.xml files that doesn't do anything.

        The main reason to switch to this would be network efficiency (loading several .ui.xml files at once, instead of in separate requests).


        3) it continues to be true that a .ui.xml file is all you have to do to create a new screen

        However, bear in mind that someone who creates a .ui.xml by referencing SmartClient documentation or by using SmartClient tools is considered a "developer" (especially since they would be likely to post here for help!). So make sure all such people are properly licensed.

        Comment

        Working...
        X