Angular2: overwrite img command in ng2-ckeditor

1k views Asked by At

I have a page that have ckeditor in there. I use ng2-ckeditor and ngx-modal. This is my template:

<div>
    <ckeditor 
        id="questionContent"
        name="questionContent"
        [(ngModel)]="question.content" 
        (change)="onChange($event)" 
        (ready)="onReady($event)"
        (focus)="onFocus($event)" 
        (blur)="onBlur($event)" debounce="500">
    </ckeditor>
</div>
....//Some stuff there
<!--Modal-->
<modal #uploadModal [closeOnEscape]="false" [closeOnOutsideClick]="false">
    <modal-header>
        <h4 class="modal-title pull-left">{{ 'QUESTIONS' | translate }}</h4>
    </modal-header>
    <modal-content>
        <div class="drag-n-drop-container"
            ngFileDrop
            [options]="options"
            (onUpload)="handleUpload($event)"
            [ngClass]="{'file-over': hasBaseDropZoneOver}"
            (onFileOver)="fileOverBase($event)">
        <h1>Drag & Drop</h1>
        <label class="upload-button">
            <input type="file"
                class="hidden"
                ngFileSelect
                [options]="options"
                (onUpload)="handleUpload($event)">
            Browse
        </label>
        </div>
    </modal-content>
    <modal-footer>
        <button class="btn btn-default pull-right cancel" (click)="uploadModal.close()">
            <i class="fa fa-times"></i>
            {{ 'BUTTON_CLOSE' | translate }}</button>
    </modal-footer>
</modal>

My situation is try to overwrite image dialog of ckeditor. So in my component I will do this:

import {
  Component, OnInit, ViewChild, ViewChildren, AfterViewChecked,
  AfterViewInit, Renderer, QueryList, ViewEncapsulation
} from '@angular/core';
import { CommonModule } from '@angular/common';
import { Router, ActivatedRoute, Params } from '@angular/router';

import { Modal } from 'ngx-modal';
import { CKButtonDirective, CKEditorComponent } from 'ng2-ckeditor';

declare var CKEDITOR: any;
@Component({
  selector: 'question-edit',
  templateUrl: './question-edit.component.html',
  styleUrls: [
    './question-edit.style.css'
  ],
  encapsulation: ViewEncapsulation.None
})
export class EditQuestionComponent implements OnInit, AfterViewChecked, AfterViewInit {
  @ViewChildren('answers') answerInputs: QueryList<any>;
  @ViewChild('uploadModal') public uploadModal: Modal;

  private editor: any;
  constructor(private rd: Renderer) { }

  ngOnInit() {

  };

  registerCKEditorCommands(editor: any, uploadModal: Modal) {
    let self = this;
    editor.addCommand("image", {
      exec: self.onUploadImage
    });
  };

  ngAfterViewInit() {
    let self = this;
    setTimeout(function () {
      for (var instanceName in CKEDITOR.instances) {
        self.editor = CKEDITOR.instances[instanceName];
        self.editor.on("instanceReady", function (ev: any) {
          let _editor = ev.editor;
          self.registerCKEditorCommands(_editor, self.uploadModal);
        });
      }
    });
  };

  onUploadImage(editor: any) {
    this.uploadModal.open();
  };
}

All work fine except when I click image button in ckeditor toolbar. It will invoke function onUploadImage() but this.uploadModal is undefined. If we try to printout this.uploadModal in function ngAfterViewInit() it give correct value and we can open dialog there.

How I can handle open dialog in function onUploadImage? Thank in advance.

1

There are 1 answers

3
yurzui On BEST ANSWER

I think any of these options should work for you because this way context will be referenced to your component instance:

1) bind

a)

editor.addCommand("image", {
  exec: this.onUploadImage.bind(this)
});

b)

export class EditQuestionComponent {
  constructor() {
    this.onUploadImage = this.onUploadImage.bind(this);
  }
  ...
  editor.addCommand("image", {
    exec: this.onUploadImage
  });

2) arrow function

editor.addCommand("image", {
  exec: (editor) => this.onUploadImage(editor)
});

3) instance arrow function

editor.addCommand("image", {
  exec: this.onUploadImage
});
...
onUploadImage = (editor: any) => {
  this.uploadModal.open();
};

See also