【问题标题】:widget binding limit: Binding not work for data change from server side小部件绑定限制:绑定不适用于服务器端的数据更改
【发布时间】:2019-08-09 18:43:43
【问题描述】:

我对小部件绑定的工作方式感到困惑,根据google document,双向绑定的工作原理:
1. 使用 UI 小部件将模型数据更新到服务器端时。
2.“对服务器名称的任何更改都会自动更新文本框中显示的文本” 但是,这不是我看到的,我看不到该小部件(例如文本框)值在服务器端数据更新后发生变化。

我在官方样品Registration Form做了一个测试,有一个所有注册项目的列表。我的测试设置是通过输入新电子邮件来更新第一个条目 (Id=1) 的电子邮件地址,并有两个按钮来更新信息:按钮“CHANGE_CLIENT”使用客户端脚本,按钮“CHANGE_SERVBER”使用服务器脚本。

CHANGE_CLIENT 代码是 onClick() 事件中的客户端脚本:

var item = widget.datasource.items.filter( a => a.Id == 1 )[0];
item.Email = widget.parent.descendants.TextBox1.value;

结果:
单击按钮,新值按预期更新到列表的第一项。信息截图

CHANGE_SERVER 代码同时具有客户端脚本和服务器脚本:
客户端脚本:

function c(newvalue) {
 google.script.run.withSuccessHandler(function() {console.log('ok');}).withFailureHandler(function() {console.log('nono');}).change(newvalue); 
}

服务器脚本:

function change(newvalue) {
 var record = app.models.Registration.getRecord('1');
  record.Email = newvalue;
  app.saveRecords([record]);
}

结果:
单击按钮成功(来自 onSuccessHandler 的日志中的“确定”),但文本框值没有改变,需要再次刷新页面才能重新加载数据源以查看新值。这不是谷歌文档“对服务器上名称的任何更改都会自动更新文本框中显示的文本”所解释的绑定。 信息截图

我希望双向绑定可以像 google 的声明那样工作,并且我的服务器代码更新可以导致 UI 值的自动更改。 由于我没有看到这种情况发生,我必须手动重新加载数据源,我希望这不是必需的,并且想知道如何让这个服务器触发绑定值更新工作,任何想法或建议表示赞赏。

更新:

我做了一个额外的测试并有更多发现:服务器端数据更新可以在客户端自动看到:

  • 从客户端修改 modelA 的值(输入编辑或客户端脚本)
  • 服务器端通过数据事件进一步更新数据,例如。 onAfterSave()
  • modelA 的实际/选中项记录的相关数据更新将自动显示在 UI 上
  • 但是,在重新加载页面/数据源之前,关系模型模型 B 的更新值不会在 UI 上更改。 我的测试显示在上面的屏幕截图中,一个具有 UnitPrice、Quantity 和 TotalPrice 的模型A,以及它的具有 doubleSum = TotalPrice * 2 的 one2one 关系模型B。我在模型A 的 onAfterSave() 数据事件中设置了服务器脚本:
record.TotalPrice = record.UnitPrice * record.Quantity;
var doublePrice = record.TotalPrice * 2;
var recordD = record.double;
recordD.doubleSum = doublePrice;
app.saveRecords([record,recordD]);

一旦更新 UnitPrice 或 Quantity,模型A 的 TotalPrice 和模型 B 的 doubleSum 值由服务器脚本更新,而模型 A 的 TotalPrice 在 UI 上自动更新,模型 B 的 doubleSum 需要重新加载页面/数据源才能在 UI 上更新。
看起来 Appmaker 只保持当前项目自己的数据(不是关系模型的)在客户端 UI 和服务器之间实时同步。 IOW,只有 SIMPLE 绑定才能看到双向绑定,以防客户端更改当前项目的值而触发更新。

【问题讨论】:

    标签: google-app-maker


    【解决方案1】:

    双向绑定的概念具有误导性。在您的客户端更改示例中,这是双向绑定。让我详细解释一下……

    在表格中,第一项具有电子邮件 new@g.com。该电子邮件值由绑定到服务器上电子邮件字段的 标签 小部件显示。当您单击CHANGE_CLIENT 按钮时,您首先更改了客户端上的信息。这就是表格行上的 Label 小部件得到更新,然后在服务器上更新的原因。这就是

    的意思

    此外,对服务器名称的任何更改都会自动更新文本框中显示的文本。

    那是因为它给出了它在服务器上以及随后在客户端上发生更改的效果。换句话说,您用来放置新值的文本框不使用绑定,因此您需要使用客户端脚本来更新客户端上的值,然后触发事件以更新服务器上的值。

    现在,当您使用服务器脚本执行更改时,客户端中的数据永远不会更新,因为需要重新加载记录。为此,您的脚本应如下所示:

    function c(newvalue) {     
        google.script.run.withSuccessHandler(function(){
            console.log('ok');
            app.datasources.TheDatasource.item._reload();
        }).withFailureHandler(function(err){
            console.log(err);
        }).change(newvalue); 
    }
    

    实际上,双向绑定仅指发生在客户端的更改并反映在服务器上。我认为应该更改文档的措辞以避免混淆。

    【讨论】:

    • 感谢您的解释,所以,我得到了: 1. UI 输入或客户端脚本触发的数据更改将自动显示在 UI 上并同步/推送到服务器端数据库。 2. 引导数据更改的服务器脚本需要重新加载数据源才能在 UI 上显示。我看到数据源重新加载在其他场景中的重要性,例如,在上面提到的列表中,数据源是 Id 的后代,无论排序和分页设置如何,新项目都将附加在列表的末尾。我向 Google issuetracker.google.com/issues/139121048 发布了问题请求
    • 我不知道这是否可能,但它会很酷。那么就不需要像我在这里解释的答案stackoverflow.com/a/50126521/5983596 那样集成firebase
    • 感谢分享这个想法数据源同步性能。同时,我在问题中更新了一个额外的测试,它表明可以在限制下看到双向绑定。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-03
    • 2021-10-07
    • 2017-02-28
    • 1970-01-01
    • 2020-05-03
    • 2011-09-07
    • 1970-01-01
    相关资源
    最近更新 更多