24

インタラクティブな JavaScript 編集にACEエディターを使用しています。エディターを JavaScript モードに設定すると、ACE はコードが有効かどうかを自動的に判断し、有効でない場合はエラー メッセージと行番号を強調表示します。

イベント ハンドラー中に、changeACE がコードが有効であると判断したかどうかを、試行する前に検出したいと考えてeval()います。私がそれを行うかもしれないと思った唯一の方法は次のとおりです。

var jsMode = require("ace/mode/javascript").Mode;
var editor = ace.edit('mycode'), edEl = document.querySelector('#mycode');
editor.getSession().setMode(new jsMode);
editor.getSession().on('change',function(){
  // bail out if ACE thinks there's an error
  if (edEl.querySelector('div.ace_gutter-cell.ace_error')) return;
  try{
    eval(editor.getSession().getValue());
  }catch(e){}
});

でも:

  1. 特定のクラスを持つ UI 内の要素の存在に依存することは、非常に壊れやすいように見えますが、さらに重要なことは、
  2. 解析のための視覚的な更新は、コールバックが発生した後changeに発生します。

したがって、実際には 500 ミリ秒以上 (JavaScript ワーカーが起動するまでの遅延) 待たなければなりません。

editor.getSession().on('change',function(){
  setTimeout(function(){
    // bail out if ACE thinks there's an error
    if (edEl.querySelector('div.ace_gutter-cell.ace_error')) return;
    try{
      eval(editor.getSession().getValue());
    }catch(e){}
  },550); // Must be longer than timeout delay in javascript_worker.js
});

JS モードの文書化されていない API で、エラーがあるかどうかを尋ねるより良い方法はありますか?

4

4 に答える 4

28

注釈が変更されると、現在のセッションでonChangeAnnotationイベントが発生します。

その後、新しい注釈セットは次のように取得できます

var annotations = editor.getSession().getAnnotations();

トリックを行うようです。キーとして、配列をとして持つ JSON オブジェクトを返します。配列には、各行に複数の注釈があるかどうかに応じて、複数のオブジェクトが含まれる場合があります。

構造は次のとおりです (firebug からコピー – 私が書いたテスト スクリプト用)

// annotations would look like
({

82:[
    {/*annotation*/
        row:82, 
        column:22, 
        text:"Use the array literal notation [].", 
        type:"warning", 
        lint:{/*raw output from jslint*/}
    }
],

rownumber : [ {anotation1}, {annotation2} ],

...

});

それで..

editor.getSession().on("changeAnnotation", function(){

    var annot = editor.getSession().getAnnotations();

    for (var key in annot){
        if (annot.hasOwnProperty(key))
            console.log("[" + annot[key][0].row + " , " + annot[key][0].column + "] - \t" + annot[key][0].text);
    }

});

// thanks http://stackoverflow.com/a/684692/1405348 for annot.hasOwnProperty(key) :)

注釈が変更されると、現在の Ace 編集セッションのすべての注釈のリストが表示されます。

お役に立てれば!

于 2012-05-19T17:12:07.883 に答える
3

おそらくDOMをトラバースするよりも速い解決策を見つけました。エディターのセッションには、使用できる getAnnotations メソッドがあります。各アノテーションには、エラーかどうかを示すタイプがあります。

「変更」時のコールバックを設定する方法は次のとおりです

function callback() {
    var annotation_lists = window.aceEditor.getSession().getAnnotations();
    var has_error = false;

    // Unfortunately, you get back a list of lists. However, the first list is
    //   always length one (but not always index 0)
    go_through:
    for (var l in annotation_lists) {
        for (var a in annotation_lists[l]) {
            var annotation = annotation_lists[l][a];
            console.log(annotation.type);
            if (annotation.type === "error") {
                has_error = true;
                break go_through;
            }
        }
    }

    if (!has_error) {
        try {
            eval(yourCodeFromTextBox);
            prevCode = yourCodeFromTextBox;
        }
        catch (error) {
            eval(prevCode);
        }
    }
}

私の知る限り、注釈には「警告」と「情報」の 2 つのタイプがあります。念のため、それらも確認したい場合に備えてください。

コードにはエラーがあり、注釈のリストにはないことがよくあるため、グローバル (コールバック関数の範囲外) で機能する以前のコードを追跡しました。その場合、エラーが発生したコードを評価するとき、それは code であり、代わりに古いコードを評価します。

2 つの eval は遅くなるように見えますが、これまでのところ、パフォーマンスはそれほど悪くないように思えます。

于 2012-03-30T04:05:33.357 に答える
2

Ace はJsHint内部的に ( workerで) 使用し、ファイルでわかるように、発行されたイベントがあります。

this.sender.emit("jslint", lint.errors);

このイベントにサブスクライブするか、必要に応じて JSHint コードを自分で呼び出すことができます (コードはかなり短いです) 。

于 2012-03-02T09:47:24.877 に答える
2

Ace 1.1.7 でワーカー イベントをサブスクライブできることがわかりました。

JavaScript コードの場合は、'jslint' イベントをサブスクライブします。

session.setMode('ace/mode/javascript}');
session.on('changeMode', function() {
  if (session.$worker) {
    session.$worker.on('jslint', function(lint) {
      var messages = lint.data, types;
      if (!messages.length) return ok();
      types = messages.map(function(item) {
        return item.type;
      });
      types.indexOf('error') !== -1 ? ko() : ok();
    });
  }
});

JSON コードの場合、'error' および 'ok' イベントをサブスクライブします。

session.setMode('ace/mode/json');
session.on('changeMode', function() {

  // session.$worker is available when 'changeMode' event triggered
  // You could subscribe worker events here, whatever changes to the
  // content will trigger 'error' or 'ok' events.

  session.$worker.on('error', ko);
  session.$worker.on('ok', ok);
});
于 2015-03-19T09:36:58.283 に答える