Smalltalk Seaside - jQuery Ajax回调

时间:2015-04-20 19:22:53

标签: jquery ajax smalltalk pharo seaside

所以我使用此代码处理非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 ]
    ].

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

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

...这是行不通的,因为我显然错过了一些秘密酱。一位Seaside专家可以参与并给我一个关于将“常规”回调代码转换为“jQuery Ajax”回调代码的快速教程吗?

更新 我非常接近搞清楚这一点;在浏览网页并重新审阅Seaside书中的章节草稿后,我将Ajax-ified按钮更改为:

(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时获得了正确的值成绩单窗口。

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

MY ANSWER

我终于提出了一个更容易理解的解决方案(对我来说),而且我真的很喜欢这个解决方案:

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'.
 ]

2 个答案:

答案 0 :(得分:5)

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

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

当您使用常规表单提交时,Seaside将为您触发表单内所有字段的回调。当您想要将表单提交作为ajax请求触发时,Seaside-jQuery的#serializeForm方法还将序列化表单内所有输入字段的内容,并在ajax请求中触发服务器端的回调,就像在“标准”表单提交中。无需更改表单的实现!

接下来,您将要禁止按下提交按钮的默认浏览器行为,该按钮是在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请求上指定一个“响应生成”回调(例如,每个请求只有一个脚本,html,json回调)。这是一个逻辑限制,因为单个请求只能生成一个响应。但是,您可以添加多个“辅助”回调(例如序列化表单回调,callback:json:等等),但使用#callback:指定的回调也是Seaside代码中的主要回调。因此,我需要将self convert放在脚本回调中,而不是放在自己的回调块中。

答案 1 :(得分:2)

“什么也没发生”,因为您所做的只是向图像发送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'.