[英]How to select text in an input after a change in Angular at the right time?
I have an input box. 我有一个输入框。 When the text changes, I need to select the text.
当文本更改时,我需要选择文本。 I understand that there are many events going on and I need to wait for them to finish.
我知道发生了许多事件,我需要等待它们完成。 I put in a timeout and it works.
我设置了超时,它可以正常工作。 However I don't want to rely on a constant time.
但是我不想依赖固定的时间。 Is there any way how to select the text when Angular is finished changing the text?
Angular完成更改文本后,有什么方法可以选择文本?
Example HTML: HTML示例:
<input type="text" value="{{txt}}">
<button ng-click="select()">Press</button>
Example JS: JS示例:
angular.module('MyApp', []).controller('MyCtrl', function ($scope, $interval) {
$scope.txt = "Hello World";
$scope.select = function () {
$scope.txt = "Bye World";
// doesn't work, too early
document.querySelector("input").setSelectionRange(0, 4);
// works
$interval(function () {
document.querySelector("input").setSelectionRange(0, 4);
}, 10, 1);
}
});
Working example is JSFiddle. 工作示例是JSFiddle。
EDIT : From the answers it looks like using timeouts (even with 0 delay) is a common practice, but the question remains whether this will guarantee that the selection happens after Angular finishes updating the text. 编辑 :从答案看来,使用超时(即使延迟为0)是一种常见做法,但是问题仍然在于,这是否可以保证选择在Angular完成更新文本后发生。
You can use $timeout with 0 delay for this purpose. 为此,您可以将$ timeout与0延迟一起使用。
$timeout(function(){
document.querySelector("input").setSelectionRange(0, 4);
});
Angular changes the DOM in next $digest
cycle, it is extremely fast, but it won't be available as soon as you run $scope.x = ??
Angular在下一个
$digest
周期中更改DOM,它的速度非常快,但是在运行$scope.x = ??
后将不可用。 . 。 Normally we would use
$timeout
to "wait" in this case. 通常,在这种情况下,我们将使用
$timeout
来“等待”。
$timeout 0 delay is in fact good enough since angular's dirty checking (and $digest cycle) happens synchronously. 实际上,由于角度的脏检查(和$ digest循环)是同步发生的,因此$ timeout 0延迟已经足够了。 (0 delay would only fire up when the current process is free).
(仅当当前进程空闲时才触发0延迟)。
If you really really want to guarantee it, here's how: 如果您真的要保证,请按照以下步骤操作:
angular.module('MyApp', []).controller('MyCtrl', function ($scope, $timeout) {
$scope.txt = "Hello World";
$scope.select = function () {
$timeout(function () {
$scope.$apply(function () {
$scope.txt = "Bye World";
});
document.querySelector("input").setSelectionRange(0, 4);
});
};
});
You have to use timeout to wrap the $apply, because the scope function would trigger a $digest and you cannot call $digest within a $digest cycle($apply calls $digest for you). 您必须使用超时来包装$ apply,因为范围函数会触发$ digest,并且您不能在$ digest周期内调用$ digest($ apply为您调用$ digest)。 $apply here guarantee the scope variable is updated, hence your setSelectionRange would only happen after the update.
$ apply在此处保证范围变量已更新,因此您的setSelectionRange仅在更新后发生。
If you do not want to use $timeout
, you can fire event with ng-blur
. 如果您不想使用
$timeout
,则可以使用ng-blur
触发事件。 A blur event fires when an element has lost focus. 当元素失去焦点时会触发模糊事件。
HTML: HTML:
<div ng-controller="MyCtrl">
<form>
<input type="text" ng-blur="select()" value="{{txt}}">
<button>Press</button>
</form>
</div>
Script: 脚本:
angular.module('MyApp', []).controller('MyCtrl', function ($scope, $interval) {
$scope.select = function () {
document.querySelector("input").setSelectionRange(0, 4);
}
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.