I'm confused about how widget binding works, according to google document, a two-way binding works:
1. when use UI widget to update model data to server side.
2. "any change to a name on the server automatically updates the text displayed in the text box"
However, this is not what I see, I cannot see that widget (ex. textbox) value changes following a server side data update.
I did a test in the official sample Registration Form, there is a list of all Registration items. My testing setting is to update the first entry (Id=1)'s email address by entering a new email and have two buttons to update info: button 'CHANGE_CLIENT' uses a client script, and button 'CHANGE_SERVBER' uses a server script.
CHANGE_CLIENT code is client script in onClick() event:
var item = widget.datasource.items.filter( a => a.Id == 1 )[0];
item.Email = widget.parent.descendants.TextBox1.value;
Result:
a click on the button, new value is updated into list's 1st item as expected. A screenshot for info
CHANGE_SERVER code has both client script and server script:
client script:
function c(newvalue) {
google.script.run.withSuccessHandler(function() {console.log('ok');}).withFailureHandler(function() {console.log('nono');}).change(newvalue);
}
server script:
function change(newvalue) {
var record = app.models.Registration.getRecord('1');
record.Email = newvalue;
app.saveRecords([record]);
}
Result:
a click on the button succeeded ('ok' in log from onSuccessHandler), but textbox value didn't change, need another refresh of page to have datasource re-loaded to see the new value. That is not what binding explained by Google's document "any change to a name on the server automatically updates the text displayed in the text box".
A screenshot for info
I expect that two-way binding works as google's statement, and my server codes update can lead to an automatic UI value change. As I didn't see this happening, I have to manually re-load datasource, I hope this is not necessary and want to know how to have this server triggered binding value update works, any thought or suggestion is appreciated.
UPDATE:
I did an additional test and have more finding: server side data update can be see automatically on client side when:
- a modification on modelA's value from a client side (input edit or client script)
- a server side further data update via data events, ex. onAfterSave()
- the related data update on modelA's actual/selected item record will be shown on UI automatically
- but, relation model modelB's updated value will not change on UI before a page/datasource reload.
My testing shown in above screenshot, a modelA with UnitPrice, Quantity and TotalPrice, and its one2one relation modelB with doubleSum = TotalPrice * 2. And I set Server Script in modelA's onAfterSave() data event:
record.TotalPrice = record.UnitPrice * record.Quantity;
var doublePrice = record.TotalPrice * 2;
var recordD = record.double;
recordD.doubleSum = doublePrice;
app.saveRecords([record,recordD]);
Once an update on UnitPrice or Quantity, modelA's TotalPrice and modelB's doubleSum value updated by Server Script, while modelA's TotalPrice updated on UI automatically, modelB's doubleSum requires a page/datasource reload to update on UI.
It looks that Appmaker only keep current item's own data (not relation model's) synchronised between client UI and server in real time. IOW, only SIMPLE binding can see two-way binding in case an update triggered by a change on current item's value from client side.