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 文件中,您可以使用 ID 很好地使用您的 JavaScript。
现实:仅仅因为您的 .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 个评分星
. 我也会使用 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 会容易得多。