【问题标题】:Stop operation in change()在 change() 中停止操作
【发布时间】:2019-05-02 04:18:18
【问题描述】:

有没有办法停止 model.document.on('change') 中的删除操作?

我用这个代码来听变化:

model.document.on('change',(eventInfo,batch) => {
// My code here.
}

就我所知并且可以检查所有更改而言,它工作正常。但似乎没有任何方法可以拒绝更改。

我尝试调用不同的 eventInfo.stop() 和 reset()。这两种方法都可以阻止更改,但总是会导致 model-nodelist-offset-out-of-bounds: 如果我尝试停止删除操作,则会出现异常。

我要做的是更改文本删除的工作方式,因此当用户删除文本时,我并没有真正从编辑器中删除文本,而是创建了一个标记来标记用户“删除”了哪些文本. (用于可选的变更控制)。

【问题讨论】:

  • 您似乎正在尝试在 CKEditor 5 中实现跟踪更改。我们将很快发布这样的插件(最有可能在下个月),请随时与我们联系以获取更多详细信息 (@987654321 @)
  • 该插件会作为标准 ckeditor 5 软件包的一部分提供吗? (还是需要云版本?)
  • 这将是一个商业插件,但它不需要云服务才能工作 - 可以将它与标准 CKEditor 包一起使用(无需实时协作、连接到云服务等)。 )。 cmets 插件很快也会采用同样的方法 - 可以“离线”使用它(没有云服务)。

标签: ckeditor5


【解决方案1】:

除了停止更改之外,也许您可​​以在更改后保存数据值,然后在删除发生:

var oldData = '';
var editor = ClassicEditor
    .create(document.querySelector('#editor'))
    .then(editor => {
        editor.model.document.on('change',(eventInfo, batch) => {
           if(oldData.length > editor.getData().length) {
           // or use eventInfo.source.differ.getChanges() and check for type: "remove"
                editor.setData(oldData);
            }
            oldData = editor.getData();
        });
    })
    .catch( error => {
        console.error( error );
    });

注意,您可以使用eventInfo.source.differ.getChanges() 循环查看发生的更改,并检查是否有“删除”类型的更改,而不是检查数据长度

【讨论】:

  • 这可能行得通,但是每次用户按下退格按钮时这样做似乎真的很昂贵。我确实实现了另一种 hack,在其中创建所需的标记,然后在每次用户删除某些内容时发出撤消操作,以撤消删除。到目前为止,这工作得非常好,但必须有更好的方法来做到这一点。我认为有关正在删除的确切内容的信息应该在某些数据结构中,但我无法找到该信息,并且 ckeditor 的那部分确实没有记录。
【解决方案2】:

已经应用的操作(并且在应用操作后会触发change 事件)不能被静默删除。它们需要被恢复(通过应用将模型状态恢复到前一个状态的新操作)或在它们实际应用之前被阻止。

还原操作

最明显但性能极差的解决方案是使用setData()。但是,这将重置选择并可能导致其他问题。

一个更优化的解决方案是对每个要还原的应用操作应用逆向操作。像在 git 中一样思考——你不能删除提交(好吧,你可以,但你必须强制推送,所以你不要)。相反,您应用了反向提交。

CKEditor 5 的操作允许getting their reversed conterparts。然后,您可以应用这些。但是,您需要在执行此操作后确保模型的状态是正确的——这很棘手,因为在如此低的级别上工作时,您会丢失在模型编写器中实现的规范化逻辑。

此解决方案的另一个缺点是您最终会得到空的撤消步骤。撤消步骤由批次定义。如果您将添加到批处理操作以还原已在其中的操作,则该批处理将是一个空的撤消步骤。目前,我不知道有什么机制可以将其从历史记录中删除。

因此,虽然恢复操作是可行的,但它很棘手,目前可能无法完美运行。

阻止应用操作

这是我推荐的解决方案。不要修复已经更改的模型,而要确保它根本没有更改。

CKEditor 5 功能以commands 的形式实现。命令有其isEnabled 状态。如果命令被禁用,则无法执行。

在 CKEditor 5 中,甚至支持打字等功能也以命令的形式实现(inputdeleteforwardDelete)。因此,可以通过禁用这些命令来防止打字。

【讨论】:

  • @Rainmar 我不知道它是否会改变任何东西,但它总是我需要恢复的整个批次,而不是每个操作。这就是为什么我目前的黑客解决方案只使用撤消操作。我无法禁用这些命令,因为我需要确切地知道该命令会更改/删除什么。另外:许多插件可以改变模型,所以我担心你的解决方案会导致我不得不重新实现一半的编辑器插件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多