猿问

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

我有一个关于这个问题的 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;

 }

并在它工作的超时内调用它,但如果可以的话,我想避免这种情况。


我错过了什么?


慕无忌1623718
浏览 179回答 2
2回答

白衣染霜花

Timeout 有它自己的作用域,因为它是一个闭包,所以 $scope.open = false 不会更新你的控制器 $scope.open 变量,你应该避免使用 timeout for 来更新作用域变量。您应该使用 bind as 绑定全局范围 -hideIt: function() {  this.timer = $timeout(function() {        this.open = false;      }.bind(this), 50);}

神不在的星期二

在您的超时函数中,this不引用 Dropdown 对象,而是可能引用该window对象。在 javascript 中,this总是指调用函数的对象,而不是定义它的对象。当 $timeout 调用您的回调函数时,它会使用 Dropdown 对象以外的其他对象,因为它不知道该对象。您需要this将父函数中的值捕获为闭包变量,或者使用angular.bind将回调函数绑定到 Dropdown 对象
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答