我目前正在使用服务器端的lift和d3(一个javascript可视化框架)实现所有可视化的图形可视化工具。我遇到的问题是在脚本中我想从服务器获取与会话相关的数据。
所以基本上,我的目标是在静态js脚本中编写lift-valid ajax回调。
如果您认为最佳解决方案是我已经尝试过的,请随时发布详细的答案,告诉我如何准确使用它以及它如何完全解决我的问题。
此解决方案类似于隐藏文本输入,可能更有可能工作。然而它并不优雅,这意味着我将不得不在加载时加载大量脚本,这不是很方便。
这似乎是电梯社区中首选的解决方案之一,如this discussion on the mailing list.
中所述通常,如果要从javascript函数中获取数据,那么创建REST接口。但是,此接口不会链接到任何会话。这是我从上一个问题得到的解决方案:Get json data in d3 from lift snippet
另一个解决方案是将ajaxcallback作为主脚本的参数来调用以生成我的图形。但是我希望有很多回调,我不想弄乱我的脚本的参数。
这个解决方案可以很优雅,但是我的脚本很长,我真的更喜欢它仍然是静态的。
在查看我的网页的源代码时,我发现ajaxSelect的回调是:
<select onchange="liftAjax.lift_ajaxHandler('F966066257023LYKF4=' + encodeURIComponent(this.value), null, null, null)" name="F96606625703QXTSWU" id="node_delete" class="input">
此外,还有一个变量包含网页末尾的页面状态:
var lift_page = "F96606625700QRXLDO";
所以,我想知道是否可以使用此liftAjax.lift_ajaxHandler
函数模拟我的ajaxcall是有效的。但是我不知道要使用的确切合成器。
由于我在客户端“伪造”了一个请求,我现在想在客户端获取请求并将其发送到正确的函数。这是LiftRules.dispatch
对象似乎是最佳解决方案的地方:调用它时,所有会话管理都已完成(请求已经过身份验证并链接到会话),但我不知道如何编写正确的append
函数中的一段代码。
在提升中,所有变量名称都被更改为随机字符串以增加安全性,我希望在我的应用程序中具有相同的行为,即使这可能意味着我将不得不“给”这些javascript这些值。但是,15个字符串值的数组仍然是比15个函数更好的权衡,作为javascript函数的参数。
在我的研究之后,我发现了这个页面:Mapping server functions to client actions它以某种方式解释了命名函数的目标,即使它没有引导我找到一个有效的解决方案。
答案 0 :(得分:6)
在Lift中休息不一定是无国籍人。如果您使用LiftRules.dispatch.append注册RestHelper,那么它将被有状态地处理,并且会像往常一样通过S对象获得会话信息。
由于您似乎对此感兴趣,并且之前已经提出过,所以这里有一个关于如何在Lift中注册和调用服务器端功能的更详细说明。如果你有一段时间没有使用Lift,请远离。以下内容不应以任何方式用于评估Lift或其复杂性。这纯粹是图书馆开发者级别的东西,并且大多数Lift用户对他们的开发感兴趣而不知道它。
当你创建有状态回调时,通常使用SHtml对象中的方法,你真正要做的是在用户会话的上下文中注册S.AFuncHolder类型的对象,每个对象都有一个唯一的ID。在此过程中生成的唯一ID是您遇到类似F96606625700QRXLDO
的模式时所看到的。当通过表单post,ajax或其他任何方式提交数据时,Lift将检查这些函数id的请求并执行相关的函数(如果存在)。有几个帮助器提供更多特定类型的AFuncHolder,如S.SFuncHolder(接受单个字符串查询参数)和S.BinFuncHolder(参数是多部分表单数据),但它们都返回Any和后台Lift将收集这些返回值创建适当类型的响应。例如,JsCmd将生成执行命令的JavaScriptResponse。您也可以直接返回LiftResponse。
使用S.fmapFunc方法注册AFuncHolders。你会这样称呼它
S.fmapFunc(SFuncHolder({ (str: String) =>
doSomethingAwesomeWithAString(str)
}))(id => <input type="text" name={id} value=""/>)
第一个参数是你的函数,用正确的* FuncHolder类型包装,第二个参数是一个获取生成的id并输出某些东西的函数。获取输出的某些是您将在页面上包含的内容。它应该以某种方式导致id作为查询参数发送到服务器,以便执行您的函数。
您可以使用上面的方法进行自己的Ajax调用,但当Lift进行ajax调用时,还有一些其他注意事项:
1)大多数浏览器只允许同时连接到给定域。三个似乎是神奇的数字。 2)AFuncHolders通常会关闭它们所包含的片段的范围,如果一次处理多个ajax请求,每个都在自己的线程中,就会发生不好的事情。
为解决这些问题,liftAjax.lift_ajaxHandler
函数会对每个ajax请求进行排队,确保一次只能向服务器发送一个。
这种方法的缺点是,它可能使得难以进行Ajax调用,其结果需要传递给回调。例如,JQuery自动完成功能在接受匹配列表的输入更改时提供回调函数。如果你手动调用LiftAjax.lift_ajaxHandler,你可以提供自己的回调功能,以便成功和错误,我建议您查看浏览器中这些功能的来源,以获取有关它们如何工作的更多信息。
实际上还有更多内容,比如Lift如何在ajax回调中恢复RequestVars(这就是lift_page进来的地方,但这就是我准备在星期六早上用咖啡解释的所有内容:)
祝你的应用好运!