我问自己,我是否正确行事。我遇到的问题是我希望在AngularJS更新textarea值后保留插入位置。
HTML看起来像这样:
<div ng-controlle="editorController">
<button ng-click="addSomeTextAtTheEnd()">Add some text at the end</button>
<textarea id="editor" ng-model="editor"></textarea>
</div>
我的控制器看起来像这样:
app.controller("editorController", function($scope, $timeout, $window) {
$scope.editor = "";
$scope.addSomeTextAtTheEnd = function() {
$timeout(function() {
$scope.editor = $scope.editor + " Period!";
}, 5000);
}
$scope.$watch("editor", function editorListener() {
var editor = $window.document.getElementById("editor");
var start = editor.selectionStart;
var end = editor.selectionEnd;
$scope.$evalAsync(function() {
editor.selectionStart = start;
editor.selectionEnd = end;
});
});
});
假设我开始在textarea中输入一些文字。然后我按下按钮,很快就会添加&#34;期间&#34!;在$scope.editor
值的末尾。在5秒超时期间,我再次关注textarea并编写更多文本。 5秒后,我的textarea值会更新。
我正在关注$scope.editor
值。 editorListener
将在每$digest
个周期执行。在这个循环中也会发生双向数据绑定。我需要在数据绑定后纠正插入位置。 $scope.$evalAsync(...)
是否应该在哪里进行?
答案 0 :(得分:0)
这是我用来操纵插入位置的指令;但是,正如我在评论中所说,IE存在问题。
以下内容可帮助您做出规划。我在你的问题中注意到的一件事是你提到了一个条件,用户可能会重新聚焦输入框以输入其他文本,我相信这会重置超时;这种情况会是真的吗?
而不是使用按钮添加文本,您是否只是添加它而不是?就像用户从输入框取消焦点时一样运行addSomeTextAtTheEnd函数?
如果您必须使用该按钮,并且用户重新关注输入框并输入更多内容,则应取消按钮超时。
喜欢:
myVar = setTimeout(function(){ alert("Hello"); }, 3000);
// Then clear the timeout in your $watch if there is any change to the input.
clearTimeout(myVar);
如果你这样做,也许你甚至不需要知道光标位置,因为addSomeTextAtTheEnd函数超时只会在5秒超时之前重置任何输入更改。如果发生5秒超时,则addSomeTextAtTheEnd将运行并且&#34;将文本附加到结尾&#34;喜欢它应该这样做。请提供更多信息,我会根据需要更新。
app.directive('filterElement', ['$filter', function($filter){
return {
restrict:'A', // Declares an Attributes Directive.
require: '?ngModel', // ? checks for parent scope if one exists.
link: function( scope, elem, attrs, ngModel ){
if( !ngModel ){ return }
var conditional = attrs.rsFilterElement.conditional ? attrs.rsFilterElement.conditional : null;
scope.$watch(attrs.ngModel, function(value){
if( value == undefined || !attrs.rsFilterElement ){ return }
// Initialize the following values
// These values are used to set the cursor of the input.
var initialCursorPosition = elem[0].selectionStart
var initialValueLength = elem[0].value.length
var difference = false
// Sets ngModelView and ngViewValue
ngModel.$setViewValue($filter( attrs.rsFilterElement )( value, conditional ));
attrs.$$element[0].value = $filter( attrs.rsFilterElement )( value, conditional );
if(elem[0].value.length > initialValueLength){ difference = true }
if(elem[0].value.length < initialValueLength){ initialCursorPosition = initialCursorPosition - 1 }
elem[0].selectionStart = difference ? elem[0].selectionStart : initialCursorPosition
elem[0].selectionEnd = difference ? elem[0].selectionEnd : initialCursorPosition
});
} // end link
} // end return
}]);