WebObjects/替代技術/Ruby on Rails
現實:如果你能獲得文件,WebObjects 與 Ajax 的使用相對容易,只是目前只知道一個用於 Ajax-WO 支援的庫,而且文件很少。即使如此,該庫也只能做到這一步,它只是提供新的元件來包裝一些 script.aculo.us 標籤。
此外,WO 文件一直錯誤地引導使用者使用元件操作而不是直接操作。
[也就是說,如果你避免使用 WO 的大部分功能,並且不使用元件操作,Ajax 會更容易。如果你確實使用了元件操作 - 我還沒見過不用元件操作的專案 - 那麼 Ajax 的使用似乎會清除你的頁面快取,如下所述。所以,在 WO 中使用 AJAX 真的很容易。真的很容易。只是它不起作用。]
[mschrag:雖然我同意上面評論者關於元件操作在 WO 中提供了強大功能的觀點,但 Ajax 和元件操作並非不能相容。Project Wonder 的 Ajax 元件 直接解決了在不清除頁面快取的情況下使用元件操作與 Ajax 的問題。雖然 Wonder 內部實現這些功能並非易事,但它證明了這種方法是可行的,如果你使用 PW 元件以及 ERXSession,你將免費獲得此功能。]
我明確提到了這一點,因為最近有人問我這個問題,因為他們試圖將一個 WYSIWYG JavaScript 編輯器附加到一個文字區域。
現實:實際上,真正發生的情況是,如果你在 WebObjects 中沒有為你的 TextArea 指定 name=value 或 id=value 行,它會為你生成一個唯一的行。但你可以隨意在你的 .wod 檔案中指定一個,WO 會使用它。然後由你確保它的唯一性,這樣你就不會有多個具有相同名稱的文字區域標籤。換句話說,如果你只有一個想要附加 JavaScript WYSIWYG 編輯器的文字區域,只需新增
textarea: WOText
{
id='wysiwyg';
name='wysiwyg';
value=textValue;
}
到你的 .wod 檔案中,你就可以在你的 JavaScript 中正常使用 id 了。
現實:僅僅因為你的 .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>
好的,讓我們分解一下。從 Prototype 庫來看,Ajax.Updater 的工作方式是,你給它一個 DOM 物件的 id 和一個 URL,它會用 URL 的內容替換具有該 id 的 DOM 物件。通常,你會使用一個 div 標籤來指定要更新的區域,我已經為了完整性而展示了它。對於評分,我需要一個 div 標籤來包含所有 5 個評分星
。我還會使用一個 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 中,你必須為每一類連結定義一個操作。在我的情況下,我將直接操作與頁面/元件繫結,所以我的 "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 元件,其中已經設定了所有內容:當前帖子、當前評分。然後返回自身會導致 div 重新生成。
但是,這裡有一個問題,因為從 JavaScript 呼叫的元件操作會計入你的回溯計數。由於有人可能在頁面上點選一個接一個的評分,這可能是一個問題。如果你的最大回溯計數是 10,而你頁面上有 20 個帖子,他們將無法對第 11 個頁面進行評分。
所以,Rails 有一行程式碼,而我有兩行 WOTag,但這兩行程式碼可以(也應該)透過建立一個 WODynamicElement 來直接生成連結而輕鬆組合起來。實質上,建立 "RemoteLink" WODynamicElement 來完成 Rails "link_to_remote" 呼叫所做的所有事情非常容易,即接收一個要更新的 id 以及 WOActionURL 所接受的所有選項。
但此外,WebObjects 解決方案在許多方面優於 Rails 解決方案。Rails 支援“部分頁面”和“元件”,但現實情況是元件非常重量級/緩慢,而部分頁面並不能完全實現您的預期。因此,WebObjects 解決方案透過將邏輯和狀態都封裝到元件中,最終比典型的 Rails 解決方案更 DRY(不要重複自己)並且封裝性更好。在您需要 Ajax 部分的頁面中,您指定元件,並將 Ajax 處理邏輯放在元件本身中。
我還沒有在 Rails Ajax 支援中看到任何無法透過結合 WOComponents 和 WODynamicElements 在 WO 中輕鬆實現的功能。幾乎所有 Rails 中的“Ajax 支援”都是 Prototype 中的一行程式碼。事實上,由於頁面/元件可以具有狀態,所以它可能比其他系統更容易在 WO 中完成。此外,我認為您可以構建一組提供比 Rails 更高階 Ajax 支援的 WOComponents。只是還沒有人編寫支援 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 版本。所見即所得編輯器很好,但我真的不想用另一種標籤語言定義我的對話方塊。HTML 對我來說已經足夠了。
那麼,您在 dojo/wo 中遇到了什麼問題?請考慮問題可能是 dojo,而不是 WO 本身。您可以輕鬆地為每個新的 dojo 標籤建立一個 WODynamicElement,將它們收集到元件中,並建立比直接使用 dojo 更容易使用的東西。