如何将值传递给Angular $ interval函数

时间:2014-08-26 19:41:07

标签: angularjs

条件

我有一个使用ngRepeat构建的HTML元素数组。

<li ng-repeat="person in persons">Name: {{ person.name }}. Age {{ person.age }}</li>

在我的控制器中,我试图使用Angular $ interval动态更新(随机)此人的“年龄”。

$scope.persons = [
  {name: "John Doe", age: 30},
  {name: "Peter Parker", age: 21},
  {name: "Clark Kent", age: 45},
  {name: "John Wayne", age: 33}
];    
var promiseOfYouth = [];
$scope.makeYoung = function() {
    //since persons are store in array object. 
    //loop persons to update dynamically each person age
    for(var x = 0; x < $scope.persons.length; x++) {
        //check age randomizer already running
        if ( angular.isDefined(promiseOfYouth[x]) ) return;
        //make them young!
        promiseOfYouth[x] = $interval(function() {
          console.log('x value in $interval function: '+x);
          try {
            $scope.persons[x].age = Math.floor(Math.random() * (99 - 17 + 1)) + 17;
          } catch(err) {
              console.log('"$scope.persons['+x+'].age" is not valid. Error message:'+err.message);  
          }
        }, 100, 50);
    }
}

问题

在makeYoung函数中,“x”值始终返回“4”

问题

如何将$ x的值传递给$ interval函数(在这种情况下它应该是0,1,2,3)? 有关详细信息,请查看我的jsFiddle示例here

3 个答案:

答案 0 :(得分:2)

这是一个经典的JavaScript问题。您需要在新范围中使用x才能使其工作。否则,所有闭包都使用相同x变量的值,在循环结束时为4。

请参阅the jsfiddle

function makePersonYoung(x) {
    //check age randomizer already running
    if ( angular.isDefined(promiseOfYouth[x]) ) return;
    //make them young!
    promiseOfYouth[x] = $interval(function() {
        $scope.persons[x].age = Math.floor(Math.random() * (99 - 17 + 1)) + 17;
    }, 100, 50);
}


$scope.makeYoung = function() {
    //since persons are store in array object. 
    //loop persons to update dynamically each person age
    for(var x = 0; x < $scope.persons.length; x++) {
        makePersonYoung(x);
    }
}

此解决方案具有使代码更具可读性的附加优势。

答案 1 :(得分:1)

这是javascript的quirk。那篇博文提出了几个解决方案。将x变量复制为立即执行的函数:

(function(x2) {promiseOfYouth[x2] = $interval(function() {
          console.log('x value in $interval function: '+x2);
          try {
            $scope.persons[x2].age = Math.floor(Math.random() * (99 - 17 + 1)) + 17;
          } catch(err) {
              console.log('"$scope.persons['+x2+'].age" is not valid. Error message:'+err.message);  
          }
        }, 100, 50)}(x);

或绑定函数

promiseOfYouth[x] = $interval(function(x2) {
      console.log('x value in $interval function: '+x2);
      try {
        $scope.persons[x2].age = Math.floor(Math.random() * (99 - 17 + 1)) + 17;
      } catch(err) {
          console.log('"$scope.persons['+x2+'].age" is not valid. Error message:'+err.message);  
      }
    }.bind(null, x), 100, 50);

答案 2 :(得分:0)

你可以像参数一样注入它

 promiseOfYouth[x] = $interval(function(x) {
          console.log('x value in $interval function: '+x);
          try {
            $scope.persons[x].age = Math.floor(Math.random() * (99 - 17 + 1)) + 17;
          } catch(err) {
              console.log('"$scope.persons['+x+'].age" is not valid. Error message:'+err.message);  
          }
        }, 100, 50);

fiddle example