【问题标题】:Appmaker Query on Calculated RecordsAppmaker 查询计算记录
【发布时间】:2017-10-29 22:56:05
【问题描述】:

我确定我做错了什么...但是每次我查询计算的数据源时,我都会收到错误“无法处理返回的循环对象”。

这里是要点:

我有一个计算模型,它获取用户的谷歌联系人并将全名字段放入 UI 上的表格中。目标是有一个单独的文本框,可用于搜索全名字段,然后使用搜索结果重新填充同一页面上的表格,类似于 google 联系人搜索行为的工作方式。文本框的 on value change 事件将文本框的值发送到此服务器脚本:

function searchContacts (sq) {
var ds = app.models.Contacts.newQuery();
ds.filters.FullName._contains = sq;
var results = ds.run();
return results;
}

但是每次从该函数返回值时,我都会收到循环对象错误。执行查询运行命令 (ds.run) 时,实际会触发该错误。

我也尝试过查询数据源,但我在某处读到无法查询计算模型的数据源,因为它不存在,因此您必须查询模型。

任何帮助将不胜感激。

【问题讨论】:

    标签: google-app-maker


    【解决方案1】:

    从你的问题来看,你想要做什么并不是 100% 清楚。如果您实际使用的是Calculated Model,那么您的Server Script Query 应该如下所示:

    var sq = query.parameters.SearchQuery;
    var contactsQuery = app.models.Contacts.newQuery();
    
    contactsQuery.filters.FullName._contains = sq;
    var contacts = ds.run();
    
    var results = contacts.map(function(contact) {
      var calcRecord = app.MyCalcModel.newRecord();
    
      calcRecord.Name = contact.FullName;
    
      return calcRecord;
    
    });
    
    return results;
    

    请注意,您不能从服务器脚本查询返回任意类型的对象,只能返回此特定计算模型的类型。

    但是从您的描述和错误文本的某些部分来看,如果您感觉您正在尝试使用 google.scritp.run 通过异步服务器调用加载记录。在这种情况下,您无法返回 App Maker 记录(App Script 不允许这样做),您需要将它们映射到简单的 JSON 对象。

    【讨论】:

    • 感谢您的回复。你是对的 - 我试图从客户端调用 google.script.run 并收到该错误。我已经在服务器脚本查询中尝试过您的建议,但似乎该查询实际上不起作用。我在查询运行命令之后放置了一个 console.log(contacts.length),我得到了与模型中相同数量的记录。我正在使用的测试数据应该只有一条记录。
    • 这很奇怪...您是否尝试记录服务器函数参数?与其他过滤器(_equals)一起玩吗?
    • 嗯...对我来说query.filters.FullName._contains 的工作方式类似于_startsWith(我假设Contacts 是目录模型)。
    • Contacts 是从 ContactsApp.getContacts() 中提取的计算模型。模型数组存在,我可以通过它的索引号指定一条记录......但是如果我尝试查询,我会得到整个数据源。我已经记录了数据源的长度,并且它始终是相同数量的记录。永远不会是更小的集合。
    • 您是否在计算数据源中处理此参数?没有魔法,您需要从查询中读取它并将其传递给联系人 API。您可以按照您设置的方式阅读它:var contacts = ContactsApp.getContactsByName(query.filters.FullName._contains, ContactsApp.Field.FULL_NAME);
    【解决方案2】:

    我认为我的原始帖子不是很清楚。

    我有一个计算模型,它是来自 Google 联系人的所有用户联系人(全名、电子邮件、手机等...)在 UI 上,我有一个列表小部件,其中填充了所有全名字段及以上列表小部件 用于搜索列表小部件的文本输入。因此,搜索文本框的输入更改事件会发送一个查询全名的请求,类似于 Google 联系人的搜索功能的工作原理。

    Screen Shot

    App Maker 似乎不允许您查询计算模型,所以我有这个解决方法 - 除非有人想出更好的方法:

    这是搜索文本框的 onInputChange 处理程序:

    sq = app.pages.SelectClient.descendants.TextBox1.value;
    app.datasources.SearchContacts.query.parameters.Name = sq;
    app.datasources.SearchContacts.load();
    

    这是服务器脚本代码(感谢@Pavel Shkleinik 的提醒):

    var sq = query.parameters.Name;
    
    if (sq !== null) {
     return getContactsbyName(sq);
    
    } else {
    
    return getContacts();
    }
    

    以及没有查询的服务器代码:

    function getContacts() {
    
      var results = [];
      var contacts = ContactsApp.getContacts();
      contacts.forEach(function(item) {
        var contact = app.models.Contacts.newRecord();
        contact.FullName = item.getFullName();
        var emails = item.getEmails(ContactsApp.Field.WORK_EMAIL);
        if (emails.length > 0) {
        contact.PrimaryEmail = emails[0].getAddress();
        }
        contact.LastName = item.getFamilyName();
        contact.FirstName = item.getGivenName();
        var phones  = item.getPhones(ContactsApp.Field.MOBILE_PHONE);
        if (phones.length > 0) {
        contact.Mobile = phones[0].getPhoneNumber();
        }
        var addresses = item.getAddresses(ContactsApp.Field.WORK_ADDRESS);
        if (addresses.length > 0) {
        contact.Address = addresses[0].getAddress();
        }
        results.push(contact);
        results.sort();
      });
      return results;
    
    }
    

    还有查询:

    function getContactsbyName(sq) {
    
    var results = [];
      var contacts = ContactsApp.getContactsByName(sq);
      contacts.forEach(function(item) {
        var contact = app.models.Contacts.newRecord();
        contact.FullName = item.getFullName();
        var emails = item.getEmails(ContactsApp.Field.WORK_EMAIL);
        if (emails.length > 0) {
        contact.PrimaryEmail = emails[0].getAddress();
        }
        contact.LastName = item.getFamilyName();
        contact.FirstName = item.getGivenName();
        var phones  = item.getPhones(ContactsApp.Field.MOBILE_PHONE);
        if (phones.length > 0) {
        contact.Mobile = phones[0].getPhoneNumber();
        }
        var addresses = item.getAddresses(ContactsApp.Field.WORK_ADDRESS);
        if (addresses.length > 0) {
        contact.Address = addresses[0].getAddress();
        }
        results.push(contact);
        results.sort();
      });
    
      return results;
    }
    

    这样,当不存在搜索查询时,列表会填充所有名称,然后根据需要使用搜索查询结果重新填充。

    唯一的问题是调用 Google 通讯录应用填充计算模型有时非常慢。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-02-26
      • 2011-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多