4

apps-script と Google Web アプリをいじり始めたところです。次のように「静的」(より良い言葉が必要なため) ページが設定されている基本的なアプリを構築できます。

function doGet() {
var app = UiApp.createApplication().setTitle('foo');
...set up widgets/etc
return app;
}
...handlers here

私が知る限り、どのハンドラーもリターン後まで実行を開始しません。 doGetそれが私の問題です。ドロップダウン リストへの最初の応答によってページの内容が決定されるインタラクティブなページが必要です。つまり、ユーザーにドロップ リストが表示され、ユーザーが選択して [送信] をクリックすると、その選択に基づいてリスト ボックスを設定する必要があります。

したがって、ロジックを に入れることができないように見えますdoGet。基本的に、すべてのロジックをイベント ハンドラーを介して連鎖させる必要があります。

function doGet() {
  ...set up first page and first submit handler
  return app;
}
function firstSubmitHandler(e) {
  .. respond to first submit handler, draw list boxes, set up second list handler
}
function secondSubmitHandler(e) {
  .. respond to second submit handler, yada
}

これが正しいなら、それはクレイジーです。私は何かを逃しましたか?ありがとう。

4

3 に答える 3

2

これは、新しい "Script as Web App" を作成したときに得られるサンプル スクリプトのマイナーな拡張です。私が行ったのは、最初のクリック ハンドラーで別のボタンを Ui に追加し、別のクリック ハンドラーをスコープに入れることだけです。同じ概念を使用して、動的 UI を構築できます。

// Script-as-app template, extended.
// doGet is exactly as supplied
function doGet() {
  var app = UiApp.createApplication();

  var button = app.createButton('Click Me');
  app.add(button);

  var label = app.createLabel('The button was clicked.')
                 .setId('statusLabel')
                 .setVisible(false);
  app.add(label);

  var handler = app.createServerHandler('myClickHandler');
  handler.addCallbackElement(label);
  button.addClickHandler(handler);

  return app;
}

// myClickHandler now contains a modified copy of doGet.
function myClickHandler(e) {
  //////////// Key concept: The UI app lives on after doGet exits
  var app = UiApp.getActiveApplication();

  var button = app.createButton('Click Me 2');
  app.add(button);

  var label = app.createLabel('The 2 button was clicked.')
                 .setId('statusLabel')
                 .setVisible(false);
  app.add(label);

  var handler = app.createServerHandler('myClickHandler2');
  handler.addCallbackElement(label);
  button.addClickHandler(handler);

  return app;
}

// myClickHandler2 is the original myClickHandler, as supplied
function myClickHandler2(e) {
  var app = UiApp.getActiveApplication();

  var label = app.getElementById('statusLabel');
  label.setVisible(true);

  app.close();
  return app;
}

これだけでは不十分な場合は、Google UI Builder と Apps スクリプトの使用方法の明確な例と、Serge が提供する例をご覧ください。

于 2013-01-18T01:51:50.953 に答える
2

どのタイプの Web アプリケーションでも、クライアントからの要求に応答すれば完了です。クライアントが双方向性を必要とする場合、新しいリクエストを作成する必要があります。ほとんどの Web アプリケーションでは、これはサーバーに対して XHR リクエストを行うことを意味します。apps スクリプトはハンドラーを使用してそれを簡素化しますが、概念は同じです。

なぜそれはクレイジーですか?これは、世界中のすべての Web アプリケーションが作成される方法です。サーバーは最初のページを提供し、対話性がある場合、ページは新しい要求を作成し、サーバー上でより多くのことを実行します。HTTP はステートレス プロトコルになるように設計されており、クライアントとサーバー間の永続的な接続を可能にする拡張機能がありますが、それらは控えめに使用され (即時の更新が必要なチャットなど)、非現実的なほど遅く、コストがかかります。しようとしています。

通常のデスクトップ プログラミングから Web アプリケーションに移行する場合、このモデルは最初は奇妙で直感的ではないかもしれませんが、Apps Script にとって特別なことではありません。

于 2013-01-18T14:10:58.773 に答える
1

HTML コンテンツを取得して、Google Apps Script Web ページをリロードしなくてもページに動的に挿入できます。

空の要素を設定して新しいページ コンテンツを受け取る

  <section id="ChgViewSection">
      <div id="PageOne"></div>
      <div id="PageTwo"></div>
      <div id="PageThree"></div>
      <div id="PageFour"></div>
      <div id="PageFive"></div> 
  </section>

最初はほとんどの要素を非表示に設定し、style="display:none"

  <section id="ChgViewSection">
      <div id="PageOne" style="display:block"></div>
      <div id="PageTwo" style="display:none"></div>
      <div id="PageThree" style="display:none"></div>
      <div id="PageFour" style="display:none"></div>
      <div id="PageFive" style="display:none"></div>    
    </div>
  </section>

1 つの要素を に設定しstyle="display:block"ます。それが最初に読み込まれるページになります。

ページ、メニュー、またはタブを変更するためのユーザー インターフェイスを作成します。

<div id="tabs-nested-left">
  <div class="cb" id="tabSignIn" onclick="mainStart('SignInBody', 'SignIn')">Sign In</div>
  <div class="cb" id="tabInput" onclick="mainStart('InputBlock', 'InputForm')">Input</div>
  <div class="cb" id="tabReg" onclick="mainStart('RegisterBlock', 'Register')">Registration</div>
  <div class="cb" id="tabRegExpl" onclick="mainStart('Explain', 'Explain')">Registration Explanation</div>
  <div class="cb" id="tabContact" onclick="mainStart('ContactUs', 'Contact')">Security</div>
</div>

イベント<script>を処理するためのaを記述します。onclick

<script>

function mainStart(ElmtToGoTo, FileToGet) {
   var currntShown = 'SignInBody'; //Create variable and set initial value
   //Hide the currently shown element first
   document.getElementById(currntShown).style.display = 'none';
   //
   currntShown = ElmtToGoTo;
   //display the element that will be shown.  No content is injected yet
   document.getElementById(ElmtToGoTo).style.display = 'block';

   var el = document.getElementById(ElmtToGoTo);
   // If element is empty get HTML and inject
   if (el.childNodes.length === 0) {
      //alert("it's empty!");
    //Run back end google .gs code to get new content
    google.script.run.withFailureHandler(onFailure)
      .withSuccessHandler(onGotHTML)
      .include(FileToGet);
  };

};

<script>

失敗および成功のハンドラーを HTML スクリプトに追加します。

function onGotHTML(daHTML) {
  //alert("Got HTML File!");
  document.getElementById(currntShown).innerHTML=daHTML;
  };

function onFailure(error) {
  alert("on failure ran:" + error.message);
};

サーバー側の.gsコードを記述します。

function include(filename) {
  return HtmlService.createHtmlOutputFromFile(filename)
   .getContent(); 
};

タブをクリックすると、現在表示されている<div>が非表示になり、次に<div>表示する が表示されますが、まだコンテンツはありません。<div>すでにコンテンツがある場合は、何もしません。<div>が空の場合は、 a を実行google.scriptしてサーバーからコンテンツを取得します。<div>コンテンツはクライアントに返され、成功ハンドラonGotHTMLと一緒に に注入されます。document.getElementById(currntShown).innerHTML=daHTML;

これのほとんどは DOM 操作とスタイルの変更です。しかし、それを可能にするのは、サーバーからファイル コンテンツを取得することです。<div>要素に挿入するコンテンツとともに保存されたファイルが必要です。ユーザーがメニュー項目またはタブをクリックしたときにサーバーから HTML コンテンツを取得すると、事前にすべてをロードする必要がなくなります。inline問題の 1 つは、CSS スタイル データが(すでにタグ内にある)場合を除き、後で追加できないことです。そのため、ページが最初に読み込まれるときにすべての CSS スタイル ファイルを読み込むか、スタイル設定を要素に入れる必要があります。ページの読み込み後に HTML を挿入し、ページを再読み込みせずに表示することはできますが、ページの読み込み後に CSS ファイルを含めて新しいスタイルを表示することはできません。

スタイリング用の CSS ファイルなど、おそらくいくつか省略したことがありますが、コードです。HTML/スタイル ; と全体的な戦略が表示されます。このような動的な単一ページ アプリケーションを構築できます。

于 2014-03-05T21:15:46.803 に答える