ng2-ckeditor 如何在编辑器未自动加载时将焦点设置到编辑器

ng2-ckeditor How to set focus to the editor, when the editor is NOT auto-loaded

我正在使用 ng2-ckeditor 插件。使用记录的方式设置焦点(即 on startup)不起作用,因为我使用 *ngIf 在用户单击按钮时显示编辑器。

this.ckConfig = {
  uiColor: '#F0F3F4',
  height: '350',
  extraPlugins: 'divarea',
  startupFocus: true
};

所以 startupFocus 配置选项不起作用,显然,因为此时 ckeditor 实际上不在 DOM 中。

我也尝试过使用 [hidden],因为当我的组件初始化时,编辑器在 DOM 中,但是编辑器当然是不可见的,所以无论如何它都无法获得焦点。

然后我发现我可以在编辑器实际可见并准备好进行用户交互时触发就绪事件,如下所示:

  <div *ngIf="isEditMode">
    <ckeditor id="ckeditor"
      [(ngModel)]="letterhead"
      [config]="ckConfig"
      (ready)="onReady($event)"
      debounce="500">
    </ckeditor>
  </div> 

但是在OnReady事件中,如何设置焦点呢?

编辑

深入了解 CKEditor 的内部结构后,我发现我可以在我的 onReady 事件处理程序中简单地执行此操作:

  onReady(event: any){
    event.editor.focus();
  }

这在我第一次尝试时就奏效了。现在,因为我已经重新加载了应用程序,所以它不再有效了...wth?

这可能适用于某些人:

  onReady(event: any){
    event.editor.focus();
  }

但编辑器加载大约需要 500-1000 毫秒。所以将焦点调用包装在计时器中:

  onReady(event: any){
    setTimeout(() => event.editor.focus(), 1000);
  }

但是,在我的情况下,用户可以通过单击按钮来显示或隐藏编辑器。由于 onReady 事件仅在 DOM 实际准备就绪时触发(因为它是配置选项的一部分),因此它仅触发一次。

因此需要一个更有创意的解决方案。

首先,我在我的组件中创建了一个私有变量来存储对编辑器的引用:

私人ckEditor:任何;

然后,当 onReady 第一次触发时,我存储对 ckEditor 实例的引用:

  onReady(event: any){
    this.ckEditor = event.editor;
  }

现在,当我的用户单击显示编辑器的按钮时:

  onClickEditButton(){
    this.isEditMode = true;
    this.isShowEditButton = false;
    setTimeout(() => this.ckEditor.focus(), 250);   
  }

每次显示我都可以设置焦点!耶! :)

请注意,这里的计时器可以更快,因为当用户可以单击我的编辑按钮(触发此方法)时,DOM 已完全加载(ckeditor 插件也是如此)。

以上答案对我不起作用。所以我找到了this thread。简答,使用$event.editing.view.focus().

长答案,就我而言,我需要延迟创建编辑器元素,直到用户单击包装元素(以提高性能)。用户点击之后,然后创建编辑器(用户不知道,他只是点击"looks"的区域,就像有编辑器一样)。

所以你在html中要做的是

    <ckeditor
      [editor]="editor"
      (ready)="onEditorReady($event)"
      data=""
      name="text">
    </ckeditor>

和代码

  onEditorReady($event: any) {
    $event.editing.view.focus();
  }

不需要超时。另请注意,我们没有使用 editor 实例,而是使用 $event 实例。

$event.editing.view 对象原型是 focus() 函数所在的位置。它也是一个对象,您可以查找任何您需要以编程方式执行的高级操作。例如,您可以执行 $event.editing.view.destroy()。这将破坏 ckeditor,但仍会创建一个常规的旧文本区域元素。还不确定这在哪里有用,但就在这里。