强制Julius在Yesod中重新插值或如何避免在客户端繁重的应用程序中对服务器进行双重标记

时间:2013-07-02 21:14:29

标签: haskell yesod

我的场景:站点显示来自持久后端的一堆行。用户可以将这些行添加到ajax样式(即不离开当前站点。)当提交按钮被命中时,我希望在不加载另一页的情况下发生两件事:

  • 新行应作为JSON对象发送到服务器,并添加到DB中。
  • 新行应立即添加到表中
  • 并可见。

此外,

  • 当用户刷新网站时,该表应与添加一堆行后的表格相同。错误处理很棘手,但可能,而不是我(当前)的问题。

我的实施方式如下:

getHomeR = do
  records ← runDB $ selectList …
  defaultLayout $ do
    $(widgetFile "tableWidget")

关键部分是,我不想将这些行呈现为HTML serverside ,我希望它发生 clientside ,因为客户端必须是 能够渲染它们! (并维护客户端和服务器端代码 以完全相同的方式渲染完全相同的东西 容易出错的方法。)

相反,我通过julius插值将records放在JS变量中:

var records = #{toJSON records}; // the Haskell value containing the data.

renderRow = function(jsonObject) { … }
appendRowToTable = function(row) { … }

$(document).ready(function() {
    $.each(records, function(i,v) {
        appendRowToTable(renderRow(v));
    });
});

这是我能想到的问题最优雅的解决方案。它 避免必须进行单独的 ajax调用来读出记录,即我知道我可以添加一条从DB中新获取记录并将其添加到JS的路由,但这让我觉得效率低下:它涉及到我想避免的一次往返。代替, JS和HTML基于第一个请求构建,所有内容都在一个请求中发送 快乐的一堆。问题现在发生在重新加载:


虽然records Haskell变量的内容可能会在页面之间更改 加载时,插值不会被重新评估。 Yesod假设朱利叶斯 文件,包括所有与IO相关的插值,保持不变,但是 他们没有。我最终得到了一个与records JavaScript变量不同的JavaScript变量 Haskell变量的内容,这对我来说是不可接受的。我需要 触摸Julius文件以使Yesod考虑更新它(我正在使用 默认的脚手架。也许这就是问题?)


TL; DR:我将IO依赖变量插入到Julius中,但是如果这些变量的内容发生变化,则在我手动更改Julius文件的时间戳之前,客户端不会看到更新的JavaScript文件。当IO操作的内容发生变化时,我希望重新插入JavaScript文件。或者,我们可以假设它们在每次请求时都会改变(即,是否存在某种可以设置为零的有效期?)

感谢您阅读此文字: - )


所以看起来这实际上是Yesod的一个错误,正如Michael Snoyman指出的那样。我在github上打开了这个issue

1 个答案:

答案 0 :(得分:2)

这看起来像一个错误,我能够在yesod devel站点中轻松地重现它。你可以在问题跟踪器中打开一张票,这样它就不会丢失吗?