跳轉到內容

WebObjects/替代技術/Ruby on Rails

來自 Wikibooks,開放世界中的開放書籍
(從 Programming:WebObjects/Alternative Technologies/Ruby on Rails 重定向)

Pierce T. Wetter III

[編輯 | 編輯原始碼]
神話:WebObjects 難以與 Ajax 一起使用。
[編輯 | 編輯原始碼]

現實:如果您能獲得文件,WebObjects 與 Ajax 一起使用起來相對容易,只是只知道一個用於 Ajax-WO 支援的庫,而且它沒有得到很好的記錄。即使這樣,該庫也只走到了這一步,因為它只是提供了一些新的元件來包裝一些 script.aculo.us 標籤。

此外,WO 文件總是錯誤地將人們推向元件操作,而不是直接操作。

[也就是說,如果您避免了 WO 的大部分功能,並且不使用元件操作,ajax 會更容易。如果您確實使用元件操作——而我還沒有參與過一個不使用它的專案——那麼 ajax 使用似乎會像下面描述的那樣,吹掉您的頁面快取。所以,在 WO 中使用 AJAX 真的非常容易。真的很容易。只是它不起作用。]

[mschrag:雖然我同意上面評論者關於元件操作在 WO 中提供了大量功能的說法,但 AJAX 和元件操作並不衝突的說法是不正確的。Project Wonder 的 Ajax 元件 直接解決了在不影響頁面快取的情況下將元件操作與 Ajax 一起使用的方法。雖然 Wonder 內部這些功能的實現並不簡單,但它證明了這確實是可以實現的,如果您使用 PW 元件以及 ERXSession,您將免費獲得此功能。]

神話:您無法在 WebObjects 中為標籤分配名稱或 ID 值。
[編輯 | 編輯原始碼]

我明確地提到了這一點,因為最近有人問我這個問題,因為他們試圖將一個 WYSIWYG JavaScript 編輯器分配給一個文字區域。

現實:實際上,真正發生的是,如果您在 WebObjects 中沒有為您的 TextArea 指定 name=value 或 id=value 行,它會為您生成一個唯一的行。但是,您完全可以在您的 .wod 檔案中指定一個,WO 會使用它。然後,由您來確保它是唯一的,這樣您就不會有多個具有相同名稱的文字區域標籤。換句話說,如果您只有一個希望附加 JavaScript WYSIWYG 編輯器的文字區域,只需新增

 textarea: WOText
 {
   id='wysiwyg';
   name='wysiwyg';
   value=textValue;
 }

在您的 .wod 檔案中,您可以使用 ID 很好地使用您的 JavaScript。

神話:WebObjects 生成 HTML
[編輯 | 編輯原始碼]

現實:僅僅因為您的 .wo 檔案的元件是 .html 和 .wod,並不意味著 WebObjects 只能生成 HTML。WebObjects 的本質上是一個非常、非常、非常複雜的 printf。元件的結果可以是 HTML、XML、JavaScript,甚至二進位制資料。您實際上可以在 .HTML 中放入任何您想要的內容,並將 WebObjects 當作一個巨大的合併引擎。例如,您可以使用 WebObjects 生成 PDF 檔案;它們只是文字,您可以很容易地將文字替換到 PDF 模板的中間。

[我把這個假設留在這裡,但我考慮刪除它,因為沒有人關心 WO 能夠生成一個亂七八糟的 pdf 檔案。人們關心的是像 GWT 這樣的 JavaScript 程式碼生成,而 WO 確實無法做到這一點。]

所以,我做的第一件事是,我聽說 Rails 很酷,而且讓 Ajax 很容易。我以前也聽說過,但那是當版本號為 0.13 的時候……所以我出去買了 Rails 書,你知道我發現了什麼嗎?

並不是 Rails 在 Ajax 上很牛,而是 Prototype Javascript 庫很牛。文件中大肆宣傳用一行程式碼來做 Ajax。

  <div id='<= posting.id'>
    <%= link_to_remote  [div to update] [link options] -> %>
  </div>

現實情況是,Rails 所做的只是寫了一行 JavaScript。從我新增到應用程式中的 Ajaxy “評分”程式碼來看,請看以下內容

  <div id='<WEBOBJECT name=postingID></WEBBOBJECT>'>
    <a href="#" onclick="new Ajax.Updater('<WEBOBJECT name=postingID></WEBBOBJECT>', '<WEBOBJECT name=ratePosting></WEBOBJECT>', {asynchronous:true, evalScripts:true}); return false;">1</a>
  </div>

好的,讓我們分解一下。Ajax.Updater 從 Prototype 庫的工作方式是,您為它提供一個 DOM 物件的 ID 和一個 URL,它將使用 URL 的內容替換具有該 ID 的 DOM 物件。通常,您使用一個 div 標籤指定要更新的區域,我出於完整性而顯示了它。對於評分,我需要 1 個 div 標籤來包含所有 5 個評分星

<a></a><a></a><a></a><a></a><a></a>

. 我也會使用 WOGenericContainer 來生成具有正確 ID 的 div 標籤,而不是使用 id='<WEBOBJECT name=postingID></WEBBOBJECT>' 行,但我希望它很明顯是 div 標籤。

所以 Ajaxy 部分是 <a> 標籤,而不是 div 標籤。

這裡我有一個手動構建的 <a> 標籤,帶有一段 onclick javascript 程式碼。它對 Prototype 庫進行了一次呼叫,該庫具有以下很酷的呼叫

 new Ajax.Updater( elementid, url, options)

它做的事情非常簡單:它從指定的 URL 中提取 HTML,並將具有指定 ID 的元素替換為下載的 HTML。

兩個 WebObjects 標籤指定了元素 ID 和連結,它們只是一個 WOString 和一個 WOActionURL

 postingID: WOString { currentPosting.primaryKeyString; }
 ratePosting: WOActionURL { see discussion }

現在就我而言,我是一個直接操作狂。所以我的 WOActionURL 看起來像這樣

 ratePosting :WOActionURL
 {
   directActionName="PostingRater";
   ?pkey=currentPosting.primaryKey;
   ?rating=cRating;
   ?wosid=NO;
 }

這會產生與 Rails 類似的結果,因為在 rails 中,您必須為每類連結定義一個操作。就我而言,我將 directactions 與頁面/元件繫結在一起,所以我的 “PostingRater” 頁面將返回與現有 <div> 定義匹配的元件級 HTML(減去任何 HEAD/BODY 標籤)。由於我們使用的是 WebObjects,如果我們使用一個元件構建包含的 <div> 標籤,這將非常容易,PostingRater 可以像這樣

 <WEBOBJECT name=RatingDiv></WEBOBJECT>

使用元件操作,它可以更簡單

 ratePosting: WOActionURL { action=ratePosting;}

因為 WebObjects 不同於 Rails,它可以具有有狀態元件,RatingDiv 元件實際上可以擁有所有邏輯,並將其自身作為操作的結果返回

 public WOReponse ratePosting
 {
   currentPosting.ratePosting(currentRating);
   return self; // since this is called from JavaScript
                    // return just myself, not self.page
                    // this will tell WO to render only
                    // this as a result.
 }

也就是說,javascript 的連結將進入 RatingDiv 元件,其中包含所有已設定好的內容:當前帖子、當前評分。然後返回 self 會導致 div 重新生成。

但是,這裡有一個問題,因為從 javascript 呼叫的元件操作會算作您的回溯計數。由於某人可能會向下瀏覽頁面,點選一個又一個評分,這可能是一個問題。如果您的最大回溯計數為 10,而您在一個頁面上有 20 個帖子,那麼他們將無法對第 11 個頁面進行評分。

所以,Rails 有一行程式碼,我只有兩行 WOTags,但這些程式碼可以(也應該)透過建立 WODynamicElement 來直接生成連結而輕鬆地組合在一起。本質上,建立一個 “RemoteLink” WODynamicElement 來完成 Rails “link_to_remote” 呼叫所做的一切會非常容易,即獲取要更新的 ID 以及 WOActionURL 接受的所有選項。

但此外,WebObjects 的解決方案在許多方面優於 Rails 的解決方案。Rails 支援 “部分頁面” 和 “元件”,但現實情況是,元件非常繁重/緩慢,而部分頁面無法完全滿足您的預期。所以,WebObjects 的解決方案透過將邏輯和狀態都包裝在一個元件中,最終比典型的 Rails 解決方案更 DRY(不要重複自己)並且封裝得更好。在您想要 Ajax 位的頁面中,您指定了元件,並將 ajax 處理邏輯放在元件本身中。

我還沒有在 Rails Ajax 支援中看到任何無法透過 WOComponents 和 WODynamicElements 的組合在 WO 中輕鬆完成的東西。Rail “Ajax 支援” 中幾乎所有內容都是 Prototype 中的一行程式碼。事實上,由於頁面/元件可以具有狀態,所以在 WO 中完成它可能比在其他系統中更_容易_。此外,我認為您可以構建一套 WOComponents,它們提供比 Rails 更_優越_的 Ajax 支援。只是沒有人編寫支援的 WODynamicElements 或 WOComponents。

現在,看一下 Ahmet 的 dojo Hello World 示例,我不得不說,在 WebObjects 中沒有任何東西可以阻止這樣做。本教程的 90% 是與任何特定技術無關的 JavaScript。與 PHP/ASP/ColdFusion 特定的部分定義了一個新頁面,就像您在 WebObjects 中需要做的那樣。只需在 JavaScript 中使用 WOActionURL 替換 url: 即可。

我還認為,從這個例子來看,dojo 作為 JavaScript 工具包有點弱。與 Prototype 相比,您將在 Dojo 中花費大量時間來連線 JavaScript 程式碼。或者將 dojo 與 Yahoo UI 庫進行對比

http://developer.yahoo.com/yui/

yui 中的整個 “Dialog” 東西很酷

http://developer.yahoo.com/yui/container/dialog/index.html

並且非常適合 WO 從各個部分構建頁面的模型。

再說一次,dojo 現在還只有 0.3 版本。WYSIWYG 編輯器很不錯,但我真的不想用另一種標籤語言來定義我的對話方塊。HTML 對我來說已經足夠了。

那麼,你在使用 dojo/wo 時到底遇到了什麼問題?請考慮一下,問題可能出在 dojo 上,而不是 WO 本身。你可以輕鬆地為每個新的 dojo 標籤建立一個 WODynamicElement,將它們收集到元件中,這樣比直接使用 dojo 會容易得多。

華夏公益教科書