0

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.

jack.pop
  • 683
  • 2
  • 6
  • 21

1 Answers1

0

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

yurzui
  • 205,937
  • 32
  • 433
  • 399
  • Thank for your kindly reply. The bind solution makes the uploadModal is not `undefined`. But it does not open the modal dialog correctly. It just show the backdrop modal with shadow. – jack.pop Apr 25 '17 at 07:52
  • Can you create plunker? – yurzui Apr 25 '17 at 08:35
  • Btw. I apply your solution with `bind(this)` and I change the third party `ngx-modal` to `ng2-bootstrap` and it help. So your solution should work fine. And `ngx-modal` does not handle well for that case. Thank you so much. – jack.pop Apr 25 '17 at 14:34