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
放在脚本回调中,而不是放在它自己的回调块中。
所以我有一个非 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
放在脚本回调中,而不是放在它自己的回调块中。