我必须在我的contenteditable div中插入自定义指令。
/*Editor Div*/
<div id="edBody" contenteditable="true"></div>
/*Insert one custom directive*/
<a ng-click="insertType('fibtext')">Add Directive</a>
我试过了:
<input type="button" value="Insert" ng-click="addHtmlAtCaret('<dc-tags></dc-tags>')">
/* Directive */
asignmentApp.directive('dcTags', function() {
return {
restrict: 'E',
template: 'new <b> Value </b>'
};
});
请帮帮我。小提琴: - http://jsfiddle.net/k2SUJ/1/
这是我试过的fiddle demo。
答案 0 :(得分:1)
为了让Angular了解您添加的元素并发挥其魔力,您需要 $compile
元素并将其链接到范围。
所以你需要一个带范围的控制器。您还需要将onclick
处理程序替换为 ng-click
以及 $compile
元素:
在HTML中:
<input type="button" value="..." ng-click="addHtmlAtCaret(...)">
在JS中:
app.controller('ctrl', function ($compile, $scope) {
$scope.addHtmlAtCaret = function (html) {
document.getElementById('test').focus();
...
var el = document.createElement("div");
el.innerHTML = html;
$compile(el)($scope);
...
};
});
另请参阅此 short demo 。
答案 1 :(得分:-1)
在执行粘贴之前最好保存光标并恢复它。在按钮的情况下,只有上面的工作。但是如果您在按钮上使用Popover或Dialog,并且在关闭对话框后,Content Editable Div Focus将首先在AngularJS App中使用。所以在做之前,请也这样做。 考虑这是您的内容可编辑Div,如下所示。 在ng-click和ng-keyup上我只保存可编辑DIV的当前Cursor,当用户打开一个对话框,或弹出或执行任何操作并调用addHtmlAtCaret(html)函数时,只需将光标重新调到最后一个输入位置,按照上面用户gkalpak的说明进行操作。
var saveSelection, restoreSelection;
$scope.commentKeyInput = function(keyEvent,id) { // (keyEvent.target).innerHTML='';
if (keyEvent.which === 13){
//alert('I am an alert');
}
else{
var divID='comment'+id;
savedSelection = saveSelection(document.getElementById(divID));
// savedSelection.start++;
// console.log(savedSelection.start);
}
}
$scope.commentBoxClicked=function(event,id){
try{
var divID='comment'+id;
savedSelection = saveSelection(document.getElementById(divID));
// console.log(savedSelection.start);
}
catch(e){
alert(e);
}
}
if (window.getSelection && document.createRange) {
saveSelection = function(containerEl) {
var range = window.getSelection().getRangeAt(0);
var preSelectionRange = range.cloneRange();
preSelectionRange.selectNodeContents(containerEl);
preSelectionRange.setEnd(range.startContainer, range.startOffset);
var start = preSelectionRange.toString().length;
readCounter++;
return {
start: start,
end: start + range.toString().length
}
};
restoreSelection = function(containerEl, savedSel) {
var charIndex = 0, range = document.createRange();
range.setStart(containerEl, 0);
range.collapse(true);
var nodeStack = [containerEl], node, foundStart = false, stop = false;
// console.log('Read Called '+readCounter+ " Node Type ="+node.nodeType);
// readCounter++;
while (!stop && (node = nodeStack.pop())) {
if (node.nodeType == 3) {
var nextCharIndex = charIndex + node.length;
if (!foundStart && savedSel.start >= charIndex && savedSel.start <= nextCharIndex) {
range.setStart(node, savedSel.start - charIndex);
foundStart = true;
}
if (foundStart && savedSel.end >= charIndex && savedSel.end <= nextCharIndex) {
range.setEnd(node, savedSel.end - charIndex);
stop = true;
}
charIndex = nextCharIndex;
} else {
var i = node.childNodes.length;
while (i--) {
nodeStack.push(node.childNodes[i]);
}
}
}
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
} else if (document.selection && document.body.createTextRange) {
saveSelection = function(containerEl) {
var selectedTextRange = document.selection.createRange();
var preSelectionTextRange = document.body.createTextRange();
preSelectionTextRange.moveToElementText(containerEl);
preSelectionTextRange.setEndPoint("EndToStart", selectedTextRange);
var start = preSelectionTextRange.text.length;
return {
start: start,
end: start + selectedTextRange.text.length
}
};
restoreSelection = function(containerEl, savedSel) {
var textRange = document.body.createTextRange();
textRange.moveToElementText(containerEl);
textRange.collapse(true);
textRange.moveEnd("character", savedSel.end);
textRange.moveStart("character", savedSel.start);
textRange.select();
};
}
$scope.addHtmlAtCaret = function (html) {
if (savedSelection) {
restoreSelection(document.getElementById('comment0'), savedSelection);
} //document.getElementById('comment0').focus();
var sel, range;
if (window.getSelection) {
// IE9 and non-IE
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents();
// Range.createContextualFragment() would be useful here but is
// non-standard and not supported in all browsers (IE9, for one)
var el = document.createElement("div");
el.innerHTML = html;
$compile(el)($scope);
var frag = document.createDocumentFragment(), node, lastNode;
while ( (node = el.firstChild) ) {
lastNode = frag.appendChild(node);
}
range.insertNode(frag);
// Preserve the selection
if (lastNode) {
range = range.cloneRange();
range.setStartAfter(lastNode);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
}
} else if (document.selection && document.selection.type != "Control") {
// IE < 9
document.selection.createRange().pasteHTML(html);
}
}
<div contenteditable ng-model="commentform.comment name="comment0" id="comment0" placeholder="Write a comment..." ng-keyup="commentKeyInput($event,0)" ng-click="commentBoxClicked($event,0)" ></div>