【问题标题】:Handsonetable - undo/redo over multiple instances of componentHandsontable - 撤消/重做组件的多个实例
【发布时间】:2015-07-31 23:15:26
【问题描述】:

我正在考虑在我的项目中使用 Handsontable (https://github.com/handsontable/handsontable)。

我需要在页面上有多个表格组件,

并且有两个自己的撤消/重做按钮,它们以与用户所做更改相同的顺序处理所有组件的撤消/重做操作。

我的意思是它就像用户在表 A 然后在表 B 中然后在表 A 中进行了更改。然后如果他点击撤消,然后 A 被改变,在下一次点击 B 被改变后,在下一次点击 A 被改变回来。

有没有可能做到这一点?

【问题讨论】:

    标签: javascript handsontable


    【解决方案1】:

    这样我们就可以结束这个问题,对于想要获得如何做到这一点的建议的人,这里有一个关于如何实现这个功能的简短想法:

    假设:

    • 我们有 Handsontable 实例,它们具有 undoredo 方法,根据 Handsontable 文档定义如下。
    • 我们有两个带有ids #undo#redo 的按钮来触发 行为。

    方法:

    撤消 ():撤消上次编辑

    重做 ():重做编辑(用于撤销撤消)


    逻辑

    技术很简单。我们将使用两个全局数组,抽象Queues,定义为undoQredoQ,它将跟踪要修改的最后一个HOT 实例的引用。每次在任何 HOT 实例上触发 afterChange 事件、按下 redo 按钮以及按下 undo 按钮时,都会修改这些 Queues。为避免这种方法过于复杂,我们不会针对空间进行优化,但我会记下它,以便您需要时可以尝试自己做。

    免责声明:您没有提到当一张或另一张桌子处于焦点时会发生什么。 HOT 的工作方式是 ctrl-z,如果启用,将 undo 关注哪个表。如果您愿意,可以禁用此功能。

    详细实现

    第 1 步:添加事件逻辑

    如下添加afterChange事件钩子,或者如果你已经有自定义事件,则追加逻辑;这在 HOT 实例的 options 的声明中。

    afterChange: function() {
        return function(changes, source) {
            var hotInstance = this;
            // check that the `undo` event was initialized before pushing
            if (hotInstance.undo) {
                undoQ.push(this);
                redoQ = []; // IMPORTANT: this clears the redo array as do most undo operations, but you can add different logic if you'd like
            }
            // other logic if you have some
        }
    }
    

    这将在发生更改时将 RE​​FERENCE 推送到每个表。请注意,这个数组可能会变大,但不是特别大。原因是每个change 只触发一次afterChange 事件。但是,这是可以进行优化的地方。相反,如果您注意到触发此事件的次数非常多,您可以做的是检查队列中的最后一个元素是否与this 相同,如果是,则增加一个计数器而不是仅附加参考。然后在undoredo 上,减少计数器直到它们达到零,然后弹出。

    第 2 步:添加撤消和重做逻辑

    这一步更直观一点。您要做的是将以下逻辑添加到undoredo 按钮点击的回调中。

    $("#undo").on("click", function() {
        if (undoQ.length > 0) {
            var hotInstance = undoQ.shift();
            hotInstance.undo();
            redoQ.push(hotInstance);
        }
    })
    
    $("#redo").on("click", function() {
        if (redoQ.length > 0) {
            var hotInstance = redoQ.shift();
            hotInstance.redo();
            undoQ.push(hotInstance);
        }
    })
    

    我们在这里所做的是手动触发上次更改的表的相应事件。请记住,更改后,redoQ 被清空,但只要没有,您应该可以毫无问题地撤消和重做。

    应该是这样的。祝你好运!

    【讨论】:

    • 我正在考虑类似的事情。这绝对是要走的路。谢谢。
    猜你喜欢
    • 2012-07-02
    • 1970-01-01
    • 2014-04-20
    • 2011-04-02
    • 2023-03-02
    • 2016-02-18
    • 2011-03-10
    • 1970-01-01
    • 2011-11-14
    相关资源
    最近更新 更多