8

インスタンスが完全にロードされた後、CKEditor インスタンスを「読み取り専用」に設定しようとしていますが、Javascript エラーが発生します: Cannot call method 'setReadOnly' of null. 私がそれを掘り下げると、エラーはeditor.setReadOnlyメソッド内のckeditor.jsのこの行から発生しています:this.editable().setReadOnly(a);つまり、エディターは存在しますが、editable(CKEditorインスタンスの)メソッド/属性は存在しません。

以下は私のコードです。少し説明します。私のアプリは GWT と Backbone を組み合わせたものです。CKEditor 自体はバックボーン コードによって作成されますが、親要素は GWT にあるため、ここでsetEnabledアクションを開始します。

private native void setEnabledOnLoad(boolean enabled, String id) /*-{
  CKEDITOR.on("instanceReady", function(evt) {
    if(evt.editor.name === id) {
      Namespace.trigger(Namespace.Events.SET_ENABLED, enabled);
    }
  });
}-*/;

setEnabled: function(enabled) {
  this.editor.setReadOnly(!enabled);
  if(enabled){
    this.editor.focusManager.focus();
  } else {
    this.editor.focusManager.blur();
  }
}

Backbone クラスには、Namespace.Events.SET_ENABLEDそのトリガーのリスナーがありますsetEnabled

リッスンする必要がある別の CKEditor イベントはありますか? instanceReadyでのイベントはないようeditableです。私は何が欠けていますか?

EDIT
this.editorは、次のように Backbone クラスrender関数で作成されます。

this.editor = CKEDITOR.replace(this.$(this.id)[0], config);

instanceReady作成直後にリスナーを追加しない理由はsetEnabledOnLoad、インスタンスが完全に初期化される前に関数が GWT で呼び出されるためです。これは、コードを 2 か所に配置した結果です。GWT は「OK、インスタンスを作成してください」と言いましたが、GWT がコードの次の行に進み、それを有効/無効に設定しようとするまでに Backbone は終了していません。

4

3 に答える 3

9

2年後ですが、これが私の解決策です。多分他の誰かがそれが役に立つと思うでしょう。上で述べたように、イベントは editable() 関数が完全に設定される前にトリガーされたように見えるため、1 つの解決策は、読み取り専用に設定する前に終了するのを待つことです。これは醜い方法かもしれませんが、うまくいきます。

        //Delayed execution - ckeditor must be properly initialized before setting readonly
        var retryCount = 0;
        var delayedSetReadOnly = function () {
            if (CKEDITOR.instances['bodyEditor'].editable() == undefined && retryCount++ < 10) {
                setTimeout(delayedSetReadOnly, retryCount * 100); //Wait a while longer each iteration
            } else {
                CKEDITOR.instances['bodyEditor'].setReadOnly();
            }
        };
        setTimeout(delayedSetReadOnly, 50);
于 2015-11-06T09:17:30.747 に答える
5

instanceReadyこの方法でイベントをサブスクライブすることができます:

CKEDITOR.instances.editor.on("instanceReady", onInstanceReadyHandler) 

ただし、editorインスタンスはそれまでに作成されている必要があります (CKEDITOR.instancesデバッガーで調べます)。

editableとの違いについて少し混乱していeditorます。コードのフラグメントをどこに表示this.editorthis.editableて割り当てられますか?

[編集済み]何が起こっているかがわかると思います。CKEDITORはグローバル オブジェクトであり、すべての CKEDITOR インスタンスを保持するクラスと考えることができます。でイベントを処理しようとするのCKEDITOR.onは正しくありません。特定のインスタンスで処理する必要があります (上で示したように)。「 editor は、インスタンスをアタッチする親要素の ID であると思いますCKEDITOR(間違っている場合は修正してください)。私は Backbone に精通していませんが、通常はreplaceで行われます:

var editorInstance = CKEDITOR.replace("editor", { on: { 
    instanceReady: function(ev) { alert("editor is ready!"); }}});

ここでは、CKEDITOR の新しいインスタンスを親要素にアタッチし、同時にイベントをeditorサブスクライブします。instanceReady返されたオブジェクトは、 setReadOnlyを含む、必要なeditorInstanceすべてのAPIを提供する必要があります。親要素 ID を使用して、グローバル オブジェクトからアクセスすることもできます。一方、editableは、むしろeditorで利用可能なサービス オブジェクトです。直接使用する必要がある特定のケースは考えられません。CKEDITORCKEDITOR.instances.editor

于 2013-08-24T04:52:06.627 に答える
1

私のソリューションでこれを更新しなかったことをお詫びします。GWT 関数を CKEditor の動作からさらに切り離す必要がありました。そこで、CKEditor オブジェクトの有効状態を更新したいときに親オブジェクトから呼び出される関数を GWT の「setEnabled」に追加しました。

public void setEnabled(boolean enabled) {
    this.enabled = enabled;
    toggleCKEditorEnabled(enabled);     
}       

次に、上記の「setEnabledOnLoad」で参照されている関数を、値で SET_ENABLED イベントをトリガーする「toggleCKEditorEnabled」に変更しましたenabled

リスナーを CKEditor の特定のインスタンスにアタッチする代わりに、CKEditor インスタンスのコンテナーである Backbone MessageEntryView クラスに追加しました。initializeMessageEntryView の関数で、この行を追加しました

Namespace.on(Namespace.Events.SET_ENABLED, this.setEnabled);

これは、常に CKEditor の 1 つのインスタンスが画面にロードされているためにのみ機能します。この問題とその解決策により、CKEditor インスタンスを一度にページに追加することができなくなりました。これは、先に進んでクライアント全体を Backbone に置き換える前に説明したことです。

于 2016-08-01T21:41:33.363 に答える