2012-10-11 15 views
0

頻繁地GAS用戶(me too)不使用ServerHandler.addCallbackElement方法或以不涵蓋所有控件的方式使用。具有ServerHandler.addCallbackElement方法的背景是什麼?

什麼是擁有這種方法的背景?爲什麼GAS開發人員介紹它?將所有輸入小部件值作爲參數傳遞給所有服務器處理程序會更簡單嗎?

documentation不提供這些問題的答案。

我看到以下原因

  1. 添加小窗口作爲回調元件在多個處理程序,其處理不同組的控制的情況下,減少了瀏覽器和GAS服務器之間的流量。這是一個問題。它節省了多少流量?我認爲最多幾千字節,通常是幾百字節。考慮到現代互聯網連接速度,甚至移動連接,這是否值得?
  2. 表單包含一個類似於多個按鈕的表格式編輯控件,並且處理具有相同名稱的行元素非常舒服。這個問題很容易通過使用tags來避免。看下面的例子。如果標籤用於其他目的,解析源按鈕ID並提取行號不是問題。
  3. 在幕後使用的技術限制。如果有這樣的限制,那麼它們是什麼?
function doGet(e) { 
    var app = UiApp.createApplication(); 
    var vPanel = app.createVerticalPanel(); 
    var handler = app.createServerHandler("onBtnClick"); 
    var lstWidgets = []; 
    for (var i = 0; i < 10; i++) { 
    var hPanel = app.createHorizontalPanel().setTag('id_' + i); 
    var text = app.createTextBox().setName("text_" + i); 
    text.setText(new Date().valueOf()); 
    var btn = app.createButton("click me").addClickHandler(handler); 
    btn.setTag(i).setId('id_btn' + i); 
    var lbl = app.createLabel().setId("lbl_" + i); 
    hPanel.add(text); 
    hPanel.add(btn); 
    hPanel.add(lbl); 
    lstWidgets.push(text); 
    lstWidgets.push(btn); 
    vPanel.add(hPanel); 
    } 
    // The addCallbackElement calls simulate situation when all widgets values are passed to a single server handler. 
    for (var j = 0; j < lstWidgets.length; j++) { 
    handler.addCallbackElement(lstWidgets[j]); 
    } 
    app.add(vPanel); 
    return app; 
} 

function onBtnClick(e) { 
    var app = UiApp.getActiveApplication(); 
    var i = e.parameter[e.parameter.source + '_tag']; 
    var lbl = app.getElementById("lbl_" + i); 
    lbl.setText("Source ButtonID: " + e.parameter.source + ', Text: ' + e.parameter["text_" + i]); 
    return app; 
} 

回答

3

很棒的問題。 「

」它節省了多少流量?「我認爲我們還不知道,但我希望隨着時間的推移它會變得更有效率。 Here is another discussion on performance.只有谷歌的廣泛測試和改進才能真正幫助我們確定最佳實踐,因爲現在我只能說ClientHandlers顯然會比ServerHandler更好。

作爲JavaScript開發人員,我認爲我們主要用於做客戶端的東西,然後我們將PHP/ASP視爲服務器端工具。我的理解到目前爲止,我們的GAS代碼實際上運行在客戶端和服務器端(至少它調用了服務器端的功能),但它確實似乎有更多的服務器端比我們意識到的要多,並且在客戶端這似乎導致了一些「編譯」的代碼。我有點從我的Java體驗中認識到這種多層部署。

由於有很多方法可以做同樣的事情,Google可以利用這樣一個事實,即我們的代碼不是直接解釋的(任何一方)做的事情,如果我們寫作手工編碼。這就是爲什麼我認爲它會比其他解決方案更有效率,最終但可能還沒有。現在,如果你擔心性能,我建議避開GAS。也許只是爲了好玩,試着在運行時查看客戶端Web應用程序的源代碼(查看源代碼)。所以爲了讓他們最有效率地做事情,我想他們會通過讓我們以一種非常高級的方式來定義事物而受益。這爲他們解釋我們的代碼提供了最大的靈活性。

爲了具體解決你的第二個問題,我個人認爲處理函數onBtnClick()在服務器端運行,而你引用的標記(以及大部分doGet)將在客戶端的瀏覽器引擎中-側。我可以看到,如果服務器端的功能在服務器端更具靈活性(高效且強大),並且提前知道他們需要處理特定事件/請求需要多少內存。 (顯然,如果每個getElementById()調用都運行一個單獨的請求,那就像每次點擊一個鏈接到一個新的迷你網頁。)

所以現在的問題是爲什麼我的處理程序不能自動創建參數只用我在處理函數中使用的東西?我們首先提出這個問題的唯一原因是因爲UiApp中有一些東西似乎在兩端都可用。該了UiApp已經在這兩個doGet和的onClick但在的doGet定義的變量的作用域都沒有,所以這些值需要作

  • 明確保存像ScriptProperties.setProperty()或
  • 投入了UiApp某處給使用addCallbackElement()處理函數ID或
  • 明確

注意如何不得不addCallbackElement(lstWidget),因爲它不是用app.create ...構造函數創建的內UiApp對象。我的猜測是,GAS正在對Google端的Web服務實現XML兼容的SOAP調用,我們可以通過研究客戶端源代碼來弄清楚這一點。僅僅重申一下,我們也可以使用setProperty()它並不重要,甚至可以通過JDBC保存它們,然後使用處理函數中的另一個連接來檢索它們,但不知何故數據需要從客戶端傳遞到服務器, -versa。

從編程的角度來看,客戶端doGet函數的範圍中有很多可用的東西,您可能永遠都不想傳遞給服務器,或者可能存在服務器端範圍內的函數doClick()與客戶端的函數具有相同的名稱,但它們實際上可能會調用完全不同的庫函數,甚至可能在完全不同的硬件上(即使從開發人員的角度來看,它們的工作方式也是一樣)。

也許Google的團隊還沒有真正決定UiApp的工作方式,否則他們只會迫使或至少讓我們把所有東西都放在那裏。當我們根據名稱調用UiApp.getActiveApplication()時,又發現了另一種觀察,它看起來不像構造函數,而是從UiApp對象返回私有實例的方法。 (Object是之前實例化的類,並且可能在某處初始化了。)我可能沒有100%回答你的問題,但我確實嘗試過,任何來自社區的進一步見解都將清楚地被理解。

現在我可能會偏離主題,但我也可以想象,實際產品將會繼續改變,因爲他們會長期提高性能,如果我們仍然覺得我們正在編寫客戶端代碼爲那麼開發人員對Google來說是成功的。現在,如果我指出了任何錯誤,請糾正我,我剛剛開始使用這些工具,並計劃在更多的細節上跟進這個問題,因爲我瞭解更多,但現在這是我最好的解釋。

0

如果使用FormPanel中所有的子元素將被髮送到您的doPost功能。用按鈕作爲源。你的UIapp將被清理。

如果您不想使用回調來指定要發送的元素和同級。

這就是UIapp的設計。

+1

問題恰恰是爲什麼UIapp這樣設計的? (據我瞭解) –

+0

可能因爲uiapp本身不是元素。所以你需要指定一個元素的名字。如果你通過頁面上的一個按鈕發送所有的HTML,那也是一樣的。但它會衝突的第一個標籤 – Thomas

+1

@Sergeinsas是完全正確的。我很好奇爲什麼UIapp是以這種方式設計的。 – megabyte1024

相關問題