Ok, I will try to explain what I am trying to do since some time ago and the problems I had.
I have in my application two concepts: persons and contracts. A person can have many contracts.
I have a big listGrid which shows a certain view over all contracts. This listGrid is rather complex, so the listGridView.ds.xml has some important criteria which define the SQL being generated (using if/else in velocity). The tableClause
is also rather complex (with a lot of left joins), but I think this is not relevant here, since I am not using $criteria values there, only in the whereClause.
listGridView.ds.xml
When I fetch the listGrid, I set the criteria depending for example which menu the user clicked, etc.
So we have a listgrid, for example:
id, person_id, contract_id, person_name, contract_title
1, 1, 1, john, a
2, 1, 2, john, b
3, 1, 3, john, c
4, 2, 4, marc, d
So we have 3 contracts (with contract_id = 1,2,3 which belong to person=1 (john) and one contract with contract_id=4 which belong to person=2 (marc) and the listGrid shows this.
It is important to note that we have many more persons/contracts!! The records shown depend on the <whereClause>, more specifically on the $criteria variables passed in.
The user can then double click on one record on the listGrid, and a dynamic form opens. There, a lot of additional information is shown. This information can either be edited directly in the form or using some buttons.
The form uses a separate datasource: form.ds.xml, which is also quite different that the listGrid. This form is divided into tabs. In the first tab the personal information of the person can be edited. A new tab
is opened for each contract the user wants. For example:
Double click on 1,1,1,john,a:
Form opens. Its first tab contains personal information of john. The second tab contains contract information from contract a. The user can also decide to open more contracts from this person, for example b. A new tab
opens for each contract edited.
So the form is divided into valuesManagers. One for the personal information, one for each contract. The personal information is saved using the form.ds.xml datasource, and the contract tabs use a contract.ds.xml datasource.
When the user finishes editing the form, he presses the "save" button of the form. It then saves all changes to the database.
Since the listGrid and the form both use different datasources, the listGrid does not get actualized, for example when john's name is changed to johny. This is whan I want to do! I want to actualize the listGrid after the form edits.
So if we change the name "john" to "johny", I need to actualize the first three records of the listgrid.
We can also change something regarding only one contract, so if we change "a" to "z", then only the first record should be actualized.
But it is very important that ONLY THE CORRECT records regarding the whereClause are shown after the listGrid actualization.
So if we have a boolean field "shouldShow", and we have in the whereClause the following: "... and shouldShow=true", only records with shouldShow=true should be shown after the actualization.
So I had three approaches:
1) I just called invalidateCache() and reloaded the complete listgrid. This is the only approach which works well, but it is very slow, since everything must be loaded again. But this can be optimized, since we only edit 1 or 2 or 3 records, and we know which records we actualized.
For example: we want to actualize all records for user=1, since his name changed. So I tried 2 other approaches. I think to call invalidateCache() only for actualizing 1 - 2 -3 records is not very nice.
2) I tried to use updateCaches() (refer to http://forums.smartclient.com/showthread.php?t=28084 )
But I had problems with my listGrid.ds.xml because of the <whereClause>. You said:
"updateCaches() applies only client-side filtering to determine whether a record should be added to a grid. That's all the information it has, since SQL fragments are, by design, never exposed to the browser (this would be information leakage from a security perspective)."
So, in our case, the <whereClause> is not taken into account. So, in our example, records with "shouldShow=false" are also shown after the actualization, although we have a whereClause which says: "... and shouldShow=true". So the user asks himself why is he seeing records with shouldSee=false! And the user gets very confused. This is not nice.
3) I tried to use addRelatedUpdate(): Refer to http://forums.smartclient.com/showthread.php?t=28441
But I also had problems with my listGrid.ds.xml because of the <whereClause>. You said:
"The ListGrid is by design totally unaware of the customized SQL in your operationBinding. It will show or not show records based on the criteria you've applied client-side. See the ResultSet documentation for more information about automatic cache synchronization."
So the user also sees records with shouldShow=false, and the user gets confused. This is not nice.
You also said:
"You need to return to your previous code that got the updates as a separate fetch and make calls to updateCaches() if you need to fulfill this requirement."
But this is my 2) approach? Refer to 2) for the problems there.
So what is the correct approach here?
I hope I made clear what is the problem, if not, just ask :-)
I am actually almost happy with the addRelatedUpdate() (approach 3). It works almost well, and very fast. Just the issue with the <whereClause> is the problem.
As you see, I have tried a lot regarding this problem, but no good solution found. Do you really think this is a weird requirement?
I just want to update a listGrid based on a form's changes.
I would need some method "actualizeListGrid(int personId)", which fetches the record and shows it only if it should be shown (regarding the actual whereClause).
Using SmartGWT 4.0: v9.0p_2013-10-17/PowerEdition Deployment (built 2013-10-17)
I have in my application two concepts: persons and contracts. A person can have many contracts.
I have a big listGrid which shows a certain view over all contracts. This listGrid is rather complex, so the listGridView.ds.xml has some important criteria which define the SQL being generated (using if/else in velocity). The tableClause
is also rather complex (with a lot of left joins), but I think this is not relevant here, since I am not using $criteria values there, only in the whereClause.
listGridView.ds.xml
Code:
.... <operationBinding operationType="fetch" > <tableClause> (select * from v_vertraege_gemeinsame_einrichtungen union select * from v_vertraege_normale_einrichtungen) as alle_vertraege join t_person on t_person.f_person_id = alle_vertraege.person_id left join t_laender as staatsangehoerigkeit_laender on staatsangehoerigkeit_laender.f_iso_kuerzel = t_person.f_staatsangehoerigkeit1 left join t_einrichtungen as einrichtungen on einrichtungen.f_id = alle_vertraege.einrichtung_id left join t_geschwister as geschwister on geschwister.f_person_id = t_person.f_person_id left join t_adressen as adressen on adressen.f_id = t_person.f_adresse left join t_tex_texte as tGeschlecht on tGeschlecht.f_id = t_person.f_geschlecht left join t_tex_texte as tReligion on tReligion.f_id = t_person.f_religion left join ...................................................... </tableClause> <whereClause> '1' = '1' AND ( --Begin: die ganze WhereClause ( alle_vertraege.einrichtung_id in (select f_id from t_einrichtungen as t_e where #if($criteria.kategorieId) t_e.f_kategorie = $criteria.kategorieId #else 1=1 #end #if($criteria.bezeichnungId ) --Evaluiert nur wenn bezeichnungId ist angegeben and t_e.f_bezeichnung = $criteria.bezeichnungId #end .................................... ) ) --End: die ganze Where Clause #if($criteria.shouldShow ) AND f_should_show = $criteria.shouldShow #end AND alle_vertraege.vertrag_typ IN ('NORMAL','GEMEINSAME_EINRICHTUNG') AND ($defaultWhereClause) </whereClause> </operationBinding>
So we have a listgrid, for example:
id, person_id, contract_id, person_name, contract_title
1, 1, 1, john, a
2, 1, 2, john, b
3, 1, 3, john, c
4, 2, 4, marc, d
So we have 3 contracts (with contract_id = 1,2,3 which belong to person=1 (john) and one contract with contract_id=4 which belong to person=2 (marc) and the listGrid shows this.
It is important to note that we have many more persons/contracts!! The records shown depend on the <whereClause>, more specifically on the $criteria variables passed in.
The user can then double click on one record on the listGrid, and a dynamic form opens. There, a lot of additional information is shown. This information can either be edited directly in the form or using some buttons.
The form uses a separate datasource: form.ds.xml, which is also quite different that the listGrid. This form is divided into tabs. In the first tab the personal information of the person can be edited. A new tab
is opened for each contract the user wants. For example:
Double click on 1,1,1,john,a:
Form opens. Its first tab contains personal information of john. The second tab contains contract information from contract a. The user can also decide to open more contracts from this person, for example b. A new tab
opens for each contract edited.
So the form is divided into valuesManagers. One for the personal information, one for each contract. The personal information is saved using the form.ds.xml datasource, and the contract tabs use a contract.ds.xml datasource.
When the user finishes editing the form, he presses the "save" button of the form. It then saves all changes to the database.
Since the listGrid and the form both use different datasources, the listGrid does not get actualized, for example when john's name is changed to johny. This is whan I want to do! I want to actualize the listGrid after the form edits.
So if we change the name "john" to "johny", I need to actualize the first three records of the listgrid.
We can also change something regarding only one contract, so if we change "a" to "z", then only the first record should be actualized.
But it is very important that ONLY THE CORRECT records regarding the whereClause are shown after the listGrid actualization.
So if we have a boolean field "shouldShow", and we have in the whereClause the following: "... and shouldShow=true", only records with shouldShow=true should be shown after the actualization.
So I had three approaches:
1) I just called invalidateCache() and reloaded the complete listgrid. This is the only approach which works well, but it is very slow, since everything must be loaded again. But this can be optimized, since we only edit 1 or 2 or 3 records, and we know which records we actualized.
For example: we want to actualize all records for user=1, since his name changed. So I tried 2 other approaches. I think to call invalidateCache() only for actualizing 1 - 2 -3 records is not very nice.
2) I tried to use updateCaches() (refer to http://forums.smartclient.com/showthread.php?t=28084 )
But I had problems with my listGrid.ds.xml because of the <whereClause>. You said:
"updateCaches() applies only client-side filtering to determine whether a record should be added to a grid. That's all the information it has, since SQL fragments are, by design, never exposed to the browser (this would be information leakage from a security perspective)."
So, in our case, the <whereClause> is not taken into account. So, in our example, records with "shouldShow=false" are also shown after the actualization, although we have a whereClause which says: "... and shouldShow=true". So the user asks himself why is he seeing records with shouldSee=false! And the user gets very confused. This is not nice.
3) I tried to use addRelatedUpdate(): Refer to http://forums.smartclient.com/showthread.php?t=28441
But I also had problems with my listGrid.ds.xml because of the <whereClause>. You said:
"The ListGrid is by design totally unaware of the customized SQL in your operationBinding. It will show or not show records based on the criteria you've applied client-side. See the ResultSet documentation for more information about automatic cache synchronization."
So the user also sees records with shouldShow=false, and the user gets confused. This is not nice.
You also said:
"You need to return to your previous code that got the updates as a separate fetch and make calls to updateCaches() if you need to fulfill this requirement."
But this is my 2) approach? Refer to 2) for the problems there.
So what is the correct approach here?
I hope I made clear what is the problem, if not, just ask :-)
I am actually almost happy with the addRelatedUpdate() (approach 3). It works almost well, and very fast. Just the issue with the <whereClause> is the problem.
As you see, I have tried a lot regarding this problem, but no good solution found. Do you really think this is a weird requirement?
I just want to update a listGrid based on a form's changes.
I would need some method "actualizeListGrid(int personId)", which fetches the record and shows it only if it should be shown (regarding the actual whereClause).
Using SmartGWT 4.0: v9.0p_2013-10-17/PowerEdition Deployment (built 2013-10-17)
Comment