【问题标题】:Save changes in contenteditable with timestamp使用时间戳保存 contenteditable 中的更改
【发布时间】:2013-04-06 10:00:58
【问题描述】:

我有一个<div contenteditable="true" />,用户可以在其中写入,长度几乎没有限制。
div 中的数据在 MySQL 数据库中以时间戳保存。

现在我的目标是在左侧有一个小注释,告诉用户文档的每个部分何时创建(分辨率应该以天为单位)。

现在的问题是:我怎样才能最好地保存信息(什么时候发生了变化)?

到目前为止,我考虑了以下似乎都可以改进的选项:

  1. 每次用户访问文档末尾的站点时,我都会插入一个标志(例如,一个带有类和存储编辑开始的数据属性的 emtpy 跨度)。然后在调用保存脚本时将此标志保存到数据库中。这个选项可以很容易地在侧面显示日期 - 我只需将它们放在与空跨度相同的高度,跨度告诉我日期。缺点是:用户可能会意外删除时间戳跨度,并且如果用户长时间不关闭窗口,则不会插入新的时间跨度(这可以通过每 X 分钟插入新的时间戳跨度来避免,因此删除部分是更相关)
  2. 尝试在每次将数据传递到保存脚本时进行字符串差异比较,并且只保存带有时间戳的差异。然后当页面被加载时,将所有部分按正确的顺序放在一起,并在 Javascript 中将日期注释放在正确的位置。虽然这对我来说听起来像是很多开销 + 当旧部分被更改时,两个部分可能会合二为一,等等。总而言之,这些选项听起来非常复杂。

任何意见/想法/建议都非常感谢!

【问题讨论】:

  • 内容的类型是结构化的还是非结构化的?如果它是非结构化的(就像时间的代码库),那么我建议使用armel提供的解决方案。如果它是结构化的或可以结构化的,那么我和 MrFishie 提供的解决方案。
  • 内容的类型是结构化的还是非结构化的?如果它是非结构化的(如时间的代码库),那么我建议使用armel提供的合并解决方案。如果它是结构化的或可以结构化的,那么 MrFishie 和我提供的解决方案。非结构化文档处理起来更复杂,因为通常很难确定适当的更改层次结构。 (这在 Lotus Notes 中跨不同服务器的复制一直是一个非常成问题的问题。)这是我希望您考虑的评论版本。
  • @LoekBergman:输入是用户生成的,不遵循任何特定结构。

标签: php mysql diff contenteditable


【解决方案1】:

您要实现的是源代码控制领域中称为“注释”或“责备”的功能(尽管您只需要更新日期而不是日期+作者或简单的作者)。

要正确地做到这一点,您需要一种方法来制作差异(php-diff 可能会完成这项工作)并获取文本的版本。 有几种策略:

  • 存储最新版本并仅保留增量(例如统一差异,我的偏好)

  • 动态存储所有版本并计算增量

一旦您有了当前版本和 delta 列表(如果超过几十个 delta,您绝对可以缩短列表,让用户询问是否真的很重要)。您将增量组合在一起,这是注释阶段发生的地方,因为您可以记住每行来自哪个版本。编写其实很简单(从最新开始,补丁中添加的所有行都是最新的,其他需要解释,所以从下一个补丁重新开始,直到你到达你想要处理的最古老的补丁,其余行来自该版本或最早的版本,因此可以使用一些标记为“在或之前”的标志)。

Google has a diff library for Javascript 所以可以在用户机器上完成所有艰苦的工作。他们在这个库中也有补丁部分。我没有找到 annotate/blame 库。

【讨论】:

  • 谢谢 - 这听起来是个好主意。只是为了更好地理解:保存:1)我保存最新版本,2)同时我保存当前版本附带的差异。然后加载(你称之为组合):1)从当前版本开始,2)获取最新的差异并将其应用于当前版本,例如google javascript 补丁,3) 使用下一个较旧的差异重复第 2 步,直到完成。我没听错吗?
  • 是的,类似的事情,在“保存”期间一定要以事务方式工作(保存当前+保存补丁)。在“加载”期间,您必须应用补丁来完成注释工作。请注意,由于补丁是面向行的,因此注释/补丁应用程序可以简化为操作“作者和/或日期”数组,仅在行坐标上工作并让文本单独出现在补丁中(尽管它们对于恢复功能或差异版本)。 Google 库不会为您完成注释部分,但您可以从他们的代码中获得灵感。
  • 他并没有要求注释或责备(或表扬)的过程,因为这是找出谁提交代码的过程。这与搜索当前版本无关。您描述的过程是合并,是 MrFishie 和我提议的一个很好的替代方案。请参阅对一般问题的评论。
  • OP 是关于给出构成其“文本”的各个部分的创建日期。除了作者之外,“注释”过程可以提供此信息。 Horen 可以选择只关注日期,也可以添加任何其他感兴趣的注释。对于结构化/非结构化问题,Horen 表示他研究了比较字符串的想法,这就是我提出面向文本的修补的原因,但当然,如果是结构化数据,XML 修补可能更实用,这个想法仍然适用。顺便说一句,一个接一个地应用补丁不会合并。
  • @koriander 感谢您的链接。不幸的是,示例页面已损坏:code.google.com/p/daisydiff/wiki/Examplesdaisydiff 是如何工作的?
【解决方案2】:

您可以做到这一点的一种方法是为div 的修订提供一个表格。每隔一段时间,您可以在此表中添加一个新条目,其中包含内容和时间戳,因此可以跟踪所有编辑修订。然后,要找出更改的内容,您可以简单地比较两个条目,找出添加、保持不变和删除的内容。

【讨论】:

  • 这是个好主意。我看到的唯一问题是“如何”找到已添加、更改和删除的内容,以及如何将其与左侧显示的创建日期的位置相匹配。有什么想法吗?
  • 应该有一些方法可以用正则表达式来做到这一点,虽然我不太擅长。
【解决方案3】:

您应该在用户提交信息时保存此信息。用户想要查看信息的那一刻,应该几乎没有任何计算。

在后端创建两个表。在一个表中,我们称之为“currentdocs”,您始终存储最新版本的数据。当用户加载文档时,所有信息都来自这个表'currentdocs'。 在另一个表中,我们称它为“docsintime”,您保存每个新的保存。它有一个指向“currentdocs”表的外键,您可以通过选择具有该外键的最大 id 来找到该表“docsintime”中的最后一行。选择语句可以是这样的:

select id from docsintime where cur_key = x order desc limit 1;

在这两个表中,您是否为每个相关部分存储了它已更改的最新时间戳。

保存新文档时,您会在“docsintime”表中获得上次保存的版本。您将所有相关部分与该记录中的数据进行比较。如果没有差异,则将相关部分的时间戳复制到要保存的新记录中。如果它确实不同,那么您是否为该相关部分创建一个新的时间戳。 比较之后,您是否将新记录保存在两个表“currentdocs”和“docsintime”中。您更新表“currentdocs”并在表“docsintime”中插入一条新记录。只有使用新文档,您才能在表“currentdocs”中进行插入。 对于该文档的下一个请求,您只需从“currentdocs”表中收集信息。然后这个过程重新开始。

【讨论】:

    猜你喜欢
    • 2018-04-26
    • 2013-05-17
    • 2021-12-08
    • 1970-01-01
    • 2015-11-30
    • 1970-01-01
    • 1970-01-01
    • 2021-01-22
    • 1970-01-01
    相关资源
    最近更新 更多