Smalltalk 海边 - jQuery Ajax 回调

Smalltalk Seaside - jQuery Ajax Callback

所以我有一个非 Ajax 回调使用此代码工作正常('convert' 方法计算 'result' 实例变量的新值):

        html form: [
        html text: 'Number to convert: '.
        html textInput
            callback: [ :value | self setNumtoconvert: value ];
            value: numtoconvert.
        html break.
        html text: 'Result: '.
        html text: result.
        html break.
        html submitButton
            value: 'Convert';
            callback: [ self convert ]
    ].

...现在我正在尝试使用 jQuery 'Ajax-ify' 它。我一直在尝试这些方面的东西:

(html button)
    onClick: ((html jQuery ajax)
        callback: [ self convert]);
    id: 'calclink';
    with: 'Convert'.

...这是行不通的,因为我显然遗漏了一些秘诀。 Seaside 专家能否插话并给我一个关于将 'regular' 回调代码转换为 'jQuery Ajax' 回调代码的快速教程?

更新 我快要搞清楚了;在网上搜索并重新审阅 Seaside 书中的章节草稿后,我将我的 Ajax 化按钮更改为:

(html button)
    onClick: ((html jQuery ajax)
        callback:[:val | self setNumtoconvert: val.
            self convert.
            Transcript show: self getResult.]
            value:(html jQuery: '#txtNumToConvert') value;
        onComplete: ((html jQuery: '#txtResult') value: self getResult)
        );
    id: 'calclink';
    with: 'Convert'.

现在唯一的问题是如何设置'#txtResult'文本框的值; Transcript show: self getResult 显示了正确的值,但我无法获取 'onComplete' 行来更新“#txtResult”值。我可以使用 onComplete: ((html jQuery: '#txtResult') value: 'hello there') 在文本框中插入一个字符串常量,但是 self getResult 没有为文本框提供值,尽管我再次在中显示 self getResult 时得到了正确的值成绩单 window.

更新两个 我的 'onComplete' 行 确实 工作,但只有在按下按钮(计算值),刷新页面,然后再次按下按钮(在'txtResult' 文本框。我该如何解决这个问题?

我的答案

我终于想出了一个更容易理解(对我来说)而且不那么冗长的解决方案,我真的很喜欢:

renderContentOn: html
html form:[     
    html textInput
       id: #txtNumToConvert;
       callback: [ :value | self setNumtoconvert: value ];
       value: numtoconvert.
    html break.
    html span
       id: #result;
       with: result.
  html break.
  html anchor
     url: 'javascript:void(0)';
     onClick: ((html jQuery id: #result) load
       serializeForm;
       html: [self convert. html span with: result]);
     with: 'Convert to Decimal'.
 ]

"Nothing is happening" 因为您所做的只是向图像发送 AJAX 请求。但是,您似乎想要的是触发 DOM 节点的更新。这需要一个带有额外处理程序的 AJAX 请求,该处理程序使用某些渲染结果更新 DOM 元素。

你在图像方面缺少的基本上是:

  • 您要更新的元素的 ID 是什么?
  • 应该执行什么渲染代码来生成 HTML 用于替换?

我不使用 jQuery,但通过查看 Seaside jQuery 代码,我认为您的代码片段应如下所示:

(html button)
  onClick: (html jQuery ajax
    "pass the id of the element to update"
    id: 'calclink';
    callback: [ self convert];
    "specify the method to call for rendering"
    html: [ :canvas | self basicRenderMyDivOn: canvas ];
    yourself);
  id: 'calclink';
  with: 'Convert'.

首先,您还需要触发表单内字段的回调。以下代码将点击事件处理程序附加到执行 ajax 请求的按钮,该请求将序列化整个表单,然后执行按钮的回调。

(html button)
   onClick: ((html jQuery ajax)
       serializeForm;
       callback: [ self convert ]);
   id: 'calclink';
   with: 'Convert'.

当您使用常规表单提交时,Seaside 会为您触发表单内所有字段的回调。当你想以ajax请求触发表单提交时,Seaside-jQuery的#serializeForm方法也会序列化表单内所有输入字段的内容并触发它们的回调ajax 请求中的服务器端,就像在 'standard' 表单提交中一样。无需更改表单的实现!

接下来,您将要抑制按下提交按钮的默认浏览器行为,即在 POST 请求中提交表单并导致浏览器发出整页请求,这将导致 Seaside (重新)呈现页面。有几种方法可以做到这一点,但简单地更改按钮的类型是一种简单的方法:

(html button)
   bePush;
  ...

最后,您需要更新页面内容。您对 #onComplete: 的使用是正确的,只是此 javascript 代码是在您首次呈现页面时生成的。因此它在呈现页面时呈现 self getResult 的值。您想要的是执行表单提交后 的值。这需要另一个回调:

(html button)
   bePush;
   onClick: ((html jQuery ajax)
       serializeForm;
       callback: [ self convert ];
       onComplete: ((html jQuery: '#txtResult') load html: [:r | self renderTextResultContentsOn: r]));
   id: 'calclink';
   with: 'Convert'.

UPDATE 上面的代码对服务器执行了两次调用,您可以通过将回调组合成单个 ajax 请求来优化它:

(html button)
   bePush;
   onClick: ((html jQuery ajax)
       serializeForm;
       script: [:s | self convert. s << ((s jQuery: '#txtResult') html: [:r | self renderTextResultContentsOn: r])]);
   id: 'calclink';
   with: 'Convert'.

或者,更优雅地:

    (html button)
       bePush;
       onClick: ((html jQuery id: #count) load
                    serializeForm;
                    html: [:r | self convert. self renderTextResultContentsOn: r]);
       with: 'Convert'.

上面的代码生成一个 ajax 请求,该请求执行表单序列化(执行其服务器端回调)并生成脚本以修改页面上的结果。我将 self convert 放在脚本回调中的原因是 Seaside-gotcha:您只能在每个 ajax 请求上指定一个 'response generating' 回调(例如,只有一个脚本,html, json 每个请求的回调)。这是一个逻辑限制,因为单个请求只能生成单个响应。但是,您可以添加多个 'secondary' 回调(例如序列化表单回调、callback:json: 等...),但使用 #callback: 指定的回调也是 Seaside 中的主要回调代码。因此,我需要将 self convert 放在脚本回调中,而不是放在它自己的回调块中。