无法在超时内设置AngularJS范围变量

时间:2019-07-29 19:37:15

标签: javascript angularjs

我有一个解决这个问题的方法。 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 个答案:

答案 0 :(得分:2)

在您的超时功能中,this不引用Dropdown对象,而是可能引用window对象。在JavaScript this中,总是指调用该函数的任何对象,而不是指定义该对象的对象。当$ timeout调用您的回调函数时,它将使用除Dropdown对象之外的对象执行此操作,因为它不知道该对象。

相关:Javascript closures and this

您需要在父函数中将this的值捕获为闭包变量,或者使用angular.bind将您的回调函数绑定到Dropdown对象上

答案 1 :(得分:1)

由于超时是封闭的,因此它具有自己的作用域,因此$ scope.open = false不会更新控制器$ scope.open变量,因此应避免使用超时来更新作用域变量。您应该使用bind as-

来绑定全局范围
hideIt: function() {
  this.timer = $timeout(function() {
        this.open = false;
      }.bind(this), 50);
}