私はAngularjsの使用を開始しましたが、コントローラー内でDOMの現在の状態を取得する必要があるという問題があります。基本的に、私はcontenteditablediv内にテキストエディタを構築しています。div内のテキストの改訂は、ユーザーが実際にフィールドに入力するだけでなく、外部サービス(サーバーからの長いポーリングプッシュ)から行うことができます。現在、サーバーからのリビジョンが角度モデルを操作しており、ng-bind-html-unsafeディレクティブを介してビューを更新しています。これに関する唯一の問題は、これがユーザーの現在のカーソル位置とテキスト選択を吹き飛ばすことです。
問題を回避する方法を見つけましたが、コントローラーのdom要素を直接操作する必要があります。これは角度がお勧めできないようです。現在の方法の検証か、より「角度のある」ものに関する推奨事項のいずれかを探しています。
基本的に、私が行ったことは、モデルに「contentChanging」と「contentChanged」の2つのイベントを追加したことです。1つ目はモデルを更新する直前に起動され、2つ目はモデルを更新した直後に起動されます。私のコントローラーでは、このようなイベントをサブスクライブします。
//dmp is google's diff_match_patch library
//rangy is a selection management library http://code.google.com/p/rangy/wiki/SelectionSaveRestoreModule
var selectionPatch;
var selection;
scope.model.on("contentChanging", function() {
var currentText = $("#doc").html();
selection = rangy.saveSelection();
var textWithSelection = $("#doc").html();
selectionPatch = dmp.patch_make(currentText, textWithSelection);
});
scope.model.on("contentChanged", function() {
scope.$apply();
var textAfterEdit = $("#doc").html();
$("#doc").html(dmp.patch_apply(selectionPatch, textAfterEdit)[0]);
rangy.restoreSelection(selection);
});
したがって、基本的に、コンテンツが変更されているときは、編集可能領域の現在のhtmlを取得します。次に、非表示のdom要素をドキュメントに挿入するrangyプラグインを使用して、ユーザーの現在の位置と選択をマークします。非表示のマーカーのないhtmlとマーカーのあるhtmlを取得し、googleのdiff_match_patchライブラリ(dmp)を使用してパッチを作成します。
コンテンツが変更されたら、scope。$ apply()を呼び出してビューを更新します。次に、ビューから新しいテキストを取得し、以前のパッチを適用します。これにより、非表示のマーカーがhtmlに追加されます。最後に、範囲を使用して選択を復元します。
私が気に入らないのは、jqueryを使用してビューから現在のhtmlを取得し、パッチをビルドして適用する方法です。ユニットテストが少しトリッキーになり、気分が悪くなります。しかし、ランジーライブラリがどのように機能するかを考えると、それを行う別の方法を考えることはできません。