将信息传递给Google Docs Add On中的服务器端功能 [英] Passing information to server-side function in a Google Docs Add On

查看:70
本文介绍了将信息传递给Google Docs Add On中的服务器端功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在根据Google的快速入门教程

开发Google Docs插件,一>。我试图在教程中更改添加的工作流程以添加新页面,然后在该新页面上插入翻译,而不是逐行工作流程。



我有一个脚本在单个文档中工作,但我很难将其移动到Add On体系结构。我认为这与将来自客户端JS的选择传递给执行翻译的服务器端脚本有关。



以下是翻译脚本

  function translate(origin,dest,savePrefs){
Logger.log('Starting the script');
if(savePrefs == true){
var userProperties = PropertiesService.getUserProperties();
userProperties.setProperty('originLang',origin);
userProperties.setProperty('destLang',dest);
Logger.log(origin,dest);
}

var doc = DocumentApp.getActiveDocument();
var body = doc.getBody();

//为翻译材料添加分页符。
body.appendPageBreak();

//获取文档中元素的数量
var elements = body.getNumChildren();
Logger.log('有页元素');

//使用数字循环遍历文档中的每个元素。
for(var i = 0; i< elements; i ++){
var element = body.getChild(i).copy();
var type = element.getType();
Logger.log('元素类型成功,开始测试');

//为子元素测试每种类型并根据结果运行脚本
//图像作为子元素嵌套在段落中,所以第二个`if`使得
//确定在移动到下一段前没有图像。
if(type == DocumentApp.ElementType.PARAGRAPH){
if(element.asParagraph()。getNumChildren()!= 0&& element.asParagraph()。getChild(0).getType ()== DocumentApp.ElementType.INLINE_IMAGE){
var img = element.asParagraph()。getChild(0).asInlineImage()。getBlob();
body.appendImage(img);
} else if(element.asParagraph()。getNumChildren()!= 0&& element.asParagraph()。getChild(0).getType()== DocumentApp.ElementType.INLINE_DRAWING){
var drawing = element.asParagraph()。copy();
body.appendParagraph(drawing);
} else {
var text = element.asParagraph()。getText();
Logger.log(text);
var spn = LanguageApp.translate(text,origin,dest);
body.appendParagraph(spn);
}
} else if(type == DocumentApp.ElementType.TABLE){
element.asTable()。copy();
body.appendTable(element);
} else if(type == DocumentApp.ElementType.LIST_ITEM){
var list = element.asListItem()。getText();
body.appendListItem(LanguageApp.translate(list,origin,dest));


code


客户端JS是:

  $(function(){
$('#run-translation')。click(loadPreferences );
google.script.run(runTranslation)
});

函数runTranslation(){
this.disabled = true;
var origin = $('input [name = origin]:checked')。val();
var dest = $('input [name = dest]:checked')。val();
var savePrefs = $('#save-prefs')。is(':checked');
google.script.run
.runTranslation(origin,dest,savePrefs);
}

如果我硬编码要用于翻译到服务器端的语言脚本,它的作品。但只要我尝试使用单选按钮中的变量,它就不会运行。我在控制台中看不到任何错误,我无法从编辑器运行脚本来检查日志。如何调试此代码?

解决方案

从客户端Javascript调用服务器端函数



您的 google.run

  google.script.run(runTranslation )

应该是:

  google.script.run 
.withFailureHander(failFunc)//可选
.withSuccessHander(succFunc)//可选
.serverFunction(optionalParams ...);

两个Handler方法从客户端JavaScript中分配回调函数,以便在成功时调用或服务器端功能失败。在这两种情况下,客户端函数都作为唯一参数提供。



您想要与之通信的服务器端函数就好像是一种方法本身,可选参数通过分界线传递。



最简单的情况是:

  google.script。运行
.translate(origin,dest,savePrefs);



<您的发布代码中包含 runTranslation ,但服务器端函数名为 translate() ...我认为这是正确的。)





h2>调试Google Apps脚本中的异步客户端/服务器代码

所提供的调试环境不足以用于调试此类客户端/服务器交换。调试器中也存在与异步执行一起使用的弱点 - 您可以在没有看到来自onEdit触发器的日志



在这种情况下调试的最简单工具是将日志写入电子表格

p>

  / ** 
*编写消息和时间戳以记录电子表格。
* From:https://stackoverflow.com/a/32212124/1677912
* /
函数myLog(message){
var ss = SpreadsheetApp.openById(logSpreadsheetId);
var logSheet = ss.getSheetByName(Log)|| ss.insertSheet( 日志);
logSheet.appendRow([new Date(),message);

$ / code>

你可以这样从你的客户端Javascript调用它:

  google.script.run.myLog(CLIENT:+ message); 

这是一个基本的方法,但您可以通过使用实用程序函数和BetterLog库来扩展它。在我的博客条目中查看更多信息你知道吗? (您可以从客户端JavaScript登录到电子表格!)


I'm working on a Google Docs Add-On based on Google's Quickstart tutorial. I'm trying to change the workflow of the Add On in the tutorial to append a new page and then insert a translation on that new page rather than the line-by-line workflow.

I have a script working in single documents but I'm having a hard time moving it to the Add On architecture. I think it's something to do with passing selections from client-side JS to the server-side script doing the translation.

Here's the translate script

function translate(origin, dest, savePrefs) {
  Logger.log('Starting the script');
  if (savePrefs == true) {
    var userProperties = PropertiesService.getUserProperties();
    userProperties.setProperty('originLang', origin);
    userProperties.setProperty('destLang', dest);
    Logger.log(origin,dest);
  }

  var doc = DocumentApp.getActiveDocument();
  var body = doc.getBody();

  // Add a page break for the translated material.
  body.appendPageBreak();

  // Get the number of elements in the document
  var elements = body.getNumChildren();
  Logger.log('Got the page elements');

  // Use the number to loop through each element in the document.
  for( var i=0;i<elements;i++) {
   var element = body.getChild(i).copy();
    var type = element.getType();
    Logger.log('Element Types were successful. Starting tests.');    

    // Test each type for a child element and run script based on the result
    // Images are nested in a paragraph as a child, so the second `if` makes
    // sure there is no image present before moving to the next paragraph.
    if( type == DocumentApp.ElementType.PARAGRAPH ){
      if(element.asParagraph().getNumChildren() != 0 && element.asParagraph().getChild(0).getType() == DocumentApp.ElementType.INLINE_IMAGE) {
        var img = element.asParagraph().getChild(0).asInlineImage().getBlob();
        body.appendImage(img);
      } else if(element.asParagraph().getNumChildren() !=0 && element.asParagraph().getChild(0).getType() == DocumentApp.ElementType.INLINE_DRAWING) {
        var drawing = element.asParagraph().copy();
        body.appendParagraph(drawing);
      } else {
        var text = element.asParagraph().getText();
        Logger.log(text);
        var spn = LanguageApp.translate(text, origin, dest);
        body.appendParagraph(spn);
      }
    } else if(type == DocumentApp.ElementType.TABLE) {
      element.asTable().copy();
      body.appendTable(element);
    } else if(type == DocumentApp.ElementType.LIST_ITEM) {
      var list = element.asListItem().getText();
      body.appendListItem(LanguageApp.translate(list, origin, dest));
    }
  }

The client-side JS is:

$(function() {
    $('#run-translation').click(loadPreferences);
    google.script.run(runTranslation)
  });

function runTranslation() {
    this.disabled = true;
    var origin = $('input[name=origin]:checked').val();
    var dest = $('input[name=dest]:checked').val();
    var savePrefs = $('#save-prefs').is(':checked');
    google.script.run
      .runTranslation(origin, dest, savePrefs);
  }

If I hard-code the languages to use in translation into the server-side script, it works. But as soon as I try to use variables from the radio buttons, it doesn't run. I don't see any errors in the console and I can't run scripts from the editor to check the logs. How can I debug this code?

解决方案

Calling server-side functions from client Javascript

You've got a minor syntax error with google.run:

google.script.run(runTranslation)

It should be:

google.script.run
             .withFailureHander(failFunc) // Optional
             .withSuccessHander(succFunc) // Optional
             .serverFunction(optionalParams...);

The two Handler methods assign callback functions from your client-side JavaScript to be invoked in the case of success or failure of the server-side function. In both cases, the client-side function is provided as the only parameter.

The server-side function you want to communicate with is presented as if it is a method itself, with optional parameters to be passed across the divide.

The simplest case for you is:

google.script.run
             .translate(origin, dest, savePrefs);

(You had runTranslation in your posted code, but the server-side function is named translate()... I assume that's the right one.)

Now, this might will not take care of all your problems, so you wisely asked about debugging...

Debugging asynchronous client / server code in Google Apps Script

The provided debug environment isn't enough for debugging this sort of client / server exchange. There are also weaknesses in the Debugger for use with asynchronous execution - you can read more about that in Not seeing logs from onEdit trigger.

The simplest tool to get you debugging in this case would be to write logs to a spreadsheet

/**
 * Write message and timestamp to log spreadsheet.
 * From: https://stackoverflow.com/a/32212124/1677912
 */
function myLog( message ) {
  var ss = SpreadsheetApp.openById( logSpreadsheetId );
  var logSheet = ss.getSheetByName("Log") || ss.insertSheet("Log");
  logSheet.appendRow([ new Date(), message );
}

You can call this from your client-side Javascript thusly:

google.script.run.myLog( "CLIENT: " + message );

That's a basic approach, but you can extend it more through use of utility functions and the BetterLog library. See more about that in my blog entry Did you know? (You can log to a spreadsheet from client JavaScript!)

这篇关于将信息传递给Google Docs Add On中的服务器端功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆