8

CodeMirror JavaScript エディターを KnockoutJSに統合したいと考えています。Ace もあると思いますが、CodeMirror の方が簡単だと思います。

JQueryUI ウィジェットと QTip のカスタム バインディングは既に統合しましたが、これらはインターネットで見つけたコードの一部であり、非常に小さな部分を変更するだけで済みました。

残念ながら、Javascript の限界に達したようですので、ここで JavaScript Sith Masters に目を向けます。私は必ずしもすべてを私のために書いてほしくはありません.ポインタと続行方法に関するアドバイスは非常に役立ちます.

私が持っているコードの一部:

HTML (テキストエリアに既にあるカスタムバインディングを削除しましたが、ここでは関係ありません)

<body>
    <textarea id="code" cols="60" rows="8" 
              data-bind="value: condition, 
              tooltip: 'Enter the conditions', 
              codemirror: { 'lineNumbers': true, 'matchBrackets': true, 'mode': 'text/typescript' }"></textarea>
</body>

CodeMirror のカスタム バインディング ハンドラの開始:

ko.bindingHandlers.codemirror = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        var options = valueAccessor() || {};
        var editor = CodeMirror.fromTextArea($(element)[0], options);
    }
};

現時点では、これにより JS エラーは発生しませんが、1 つではなく 2 つのテキスト領域が表示されます。

次に何をすればいいですか?

4

6 に答える 6

3

さて、私はついにそれを行うことができました(更新されたfiddleを参照してください)。

カスタムテキストエリアに初期値を設定することができました。しかしその後、バインドされた要素は更新されませんでした。

ただし、CodeMirror の API を使用すると、onChangeイベントにコールバック メソッドを登録して、テキストエリアのコンテンツが変更されるたびに呼び出されるようにすることができます。したがって、バインドされた要素の値を更新するコールバックを実装するだけの問題でした。これは、オプションで、カスタム テキスト エリアの作成時に行われます。

カスタムバインディングは次のとおりです。

ko.bindingHandlers.codemirror = {
    init: function(element, valueAccessor, allBindingsAccessor, viewModel) {
        var options = $.extend(valueAccessor(), {
            onChange: function(cm) {
                allBindingsAccessor().value(cm.getValue());
            }
        });
        var editor = CodeMirror.fromTextArea(element, options);
        element.editor = editor;
        editor.setValue(allBindingsAccessor().value());
        editor.refresh();
        var wrapperElement = $(editor.getWrapperElement()); 

        ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
            wrapperElement.remove();
        });
    }
};

いくつかの機能が欠けているかもしれませんが、私が必要としているものについては完全に機能します。

編集: Anders の発言に従ってaddDisposeCallback、テンプレートが再レンダリングされたときに CodeMirror によって生成された DOM 要素を効果的に破棄する部分を追加しました。CodeMirror が生成するものはすべて 1 つのノード内にあるため、このノードを削除するだけです。

于 2012-11-14T11:51:51.847 に答える
1

上記のバインディング ハンドラーを使用しようとしていますが、何か (スペースまたはその他の文字) を入力するまで TextArea にテキストが表示されないという問題があります。

ロードが完了すると空白になり、領域に何かを入力するとすぐに、バインドされたすべてのデータが表示されます。

もう 1 つの質問です。単純な ko.observable() を TextArea の値にバインドすると、すべてがうまく機能しますが、これを ko.observableArray の列の 1 つに置き換えると、たとえば value: selectedProfile().QueryString, Iバインディング ハンドラから次のエラーが発生します。

問題の行: editor.setValue(allBindingsAccessor().value()); エラー: キャッチされていない TypeError: オブジェクト # のプロパティ '値' は関数ではありません

考え?

/LM

于 2012-11-30T12:47:50.873 に答える