我已經開始使用angular js,並且有一個問題,需要獲取我的控制器內部DOM的當前狀態。基本上我正在建立一個文本編輯器內部的contenteditable div。修改div中的文本可以來自外部服務(長時間輪詢從服務器推送)以及用戶實際在該字段中輸入的內容。現在來自服務器的修訂版正在操縱我的角度模型,然後通過ng-bind-html-unsafe指令更新視圖。唯一的問題是這會吹走用戶當前的光標位置和文本選擇。angular.js查詢DOM當前狀態的最佳實踐方式
我已經想出了一個解決問題的方法,但它需要直接在我的控制器中操作dom元素,這似乎在角度上是灰心喪氣的。我正在尋找對我目前的方法進行驗證,或者對更多「angulary」的東西進行推薦。
基本上我已經做了兩件事添加到我的模型,「contentChanging」和「contentChanged」。第一個在我更新模型之前被解僱,第二個在之後。在我的控制器中,我訂閱了這些事件。
//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。然後我使用rangy插件,它將隱藏的dom元素插入到文檔中以標記用戶當前的位置和選擇。我採用沒有隱藏標記的html和帶有標記的html,並使用谷歌的diff_match_patch庫(dmp)製作補丁。
一旦內容改變,我調用範圍。$ apply()更新視圖。然後,我從視圖中獲取新文本並應用之前的補丁,這會將隱藏的標記添加回html。最後,我使用範圍來恢復選擇。
我不喜歡的部分是我如何使用jquery從視圖中獲取當前的html來構建和應用我的修補程序。這將使單元測試有點棘手,但它感覺不對。但是,鑑於這個矮胖的圖書館是如何工作的,我想不出有另一種方式去做。
爲什麼你的文本編輯器不能成爲指令而不是控制器? – 2013-02-24 07:45:31
它可能會,這是我第一次進入角度,所以我仍然在我的腳下,我仍然需要對指令做更多的研究。從你的建議,我會想象這樣的事情。帶有兩個參數的指令:1.字符串屬性的路徑。 2.編輯方法。無論何時用戶編輯元素,該指令都會創建一個補丁並傳遞該編輯方法。然後該指令將字符串屬性的值備份到視圖。那是你在想什麼? – AndrewSwerlick 2013-02-24 20:39:49
是的,類似的東西。不知道你是否需要編輯方法。就像你說的,你會傳遞一個字符串屬性的名字來綁定。如果外面有什麼需要知道什麼時候改變了,那麼您應該在該屬性上添加一個監視。 – 2013-02-24 20:48:12