我有一个关于这个问题的 jsfiddle。 https://jsfiddle.net/uvtw5kp1/4/$scope.Dropdown = { open: false, searchValue: "", timer: null, hideIt: function() { this.timer = $timeout(function() { alert("timeout happened the value will not change"); this.open = false; }, 50); }, hideItNotimer: function() { this.open = false; }, showIt: function() { $timeout.cancel(this.timer); this.open = true; }};当我在 ng-mouseout 上调用 Dropdown.hideItNotimer() 时它没有问题,但是当我调用 Dropdown.hideIt() 时,变量没有设置。我添加了一个警报以确保计时器正常工作,并且我尝试在之后执行 scope.apply。有效的是在计时器内调用范围级别的函数:像这样: $scope.setDropdownHidden = function(){ $scope.Dropdown.open = false; }并在它工作的超时内调用它,但如果可以的话,我想避免这种情况。我错过了什么?
2 回答
白衣染霜花
TA贡献1796条经验 获得超10个赞
Timeout 有它自己的作用域,因为它是一个闭包,所以 $scope.open = false 不会更新你的控制器 $scope.open 变量,你应该避免使用 timeout for 来更新作用域变量。您应该使用 bind as 绑定全局范围 -
hideIt: function() {
this.timer = $timeout(function() {
this.open = false;
}.bind(this), 50);
}
神不在的星期二
TA贡献1963条经验 获得超6个赞
在您的超时函数中,this
不引用 Dropdown 对象,而是可能引用该window
对象。在 javascript 中,this
总是指调用函数的对象,而不是定义它的对象。当 $timeout 调用您的回调函数时,它会使用 Dropdown 对象以外的其他对象,因为它不知道该对象。
您需要this
将父函数中的值捕获为闭包变量,或者使用angular.bind将回调函数绑定到 Dropdown 对象
添加回答
举报
0/150
提交
取消