MEAN.JS堆栈$ http.post()。success()将变量传递给success()匿名函数作用域问题

时间:2014-08-02 13:37:41

标签: javascript angularjs scope mean-stack

我正努力做到这一点:

$http.post('/route/path', {'username': $scope.threadedUsers[currentIndex].name}).
    success(function(data) {
        $scope.threadedUsers[currentIndex].ID = data._id;
        $scope.threadedUsers[currentIndex].pic = data.profile_picture[0];
    }).
    error(function(data) {
        //error stuff here
    });

$ scope.threadedUsers是一个动态填充的JSON对象数组 所以$ scope.threadedUsers [0] = {' ID':'',' pic':'','消息':[],' lastTimestamp':'' }

currentIndex是一个局部变量,它引用当前正在操作的$ scope.threadedUsers数组的索引。

问题是在成功匿名函数内部,currentIndex在新范围内。现在我可以将currentIndex放在$ scope中,但这似乎是不好的做法,因为这是做这件事的唯一理由。

无论如何都要将外部值传递给成功回调函数(对于索引)?或者是使currentIndex成为$ scope变量的唯一方法吗?

2 个答案:

答案 0 :(得分:2)

您正在使用javascript for / while循环遇到一个非常常见的问题/误解,这是同步和异步函数。到异步函数时,在这种情况下执行HTTP post回调,同步循环已经运行完成,循环计数器变量已经在最终结束值。

只需将代码重构为处理单个用户的辅助方法。

function updateUser($scope, user) {
  $http.post('/route/path', {'username': user.name}).
    success(function(data) {
      user.ID = data._id;
      user.pic = data.profile_picture[0];
  }).
  error(function(data) {
    //error stuff here
  });
}

//Here's the code you omitted but is essential to your question
var updateInScope = updateUser.bind(null, $scope);
$scope.threadedUsers.forEach(updateInScope);

答案 1 :(得分:1)

似乎问题出现了,因为currentIndex在某些for循环中。

有许多方法可以避免它,其中一种方法是像Peter Lyons的回答那样重构代码。

另一种方法是,你可以记住这个闭包中的currentIndex

(function (rememberedIndex) {
    $http.post('/route/path', {'username': $scope.threadedUsers[rememberedIndex].name}).
    success(function(data) {
        $scope.threadedUsers[rememberedIndex].ID = data._id;
        $scope.threadedUsers[rememberedIndex].pic = data.profile_picture[0];
    }).
    error(function(data) {
        //error stuff here
    });
}(currentIndex));

实际上,您也可以使用相同的变量名称currentIndex,但这可能会让以后看到代码的人感到困惑。

(function (currentIndex) {
    $http.post('/route/path', {'username': $scope.threadedUsers[currentIndex].name}).
    success(function(data) {
        $scope.threadedUsers[currentIndex].ID = data._id;
        $scope.threadedUsers[currentIndex].pic = data.profile_picture[0];
    }).
    error(function(data) {
        //error stuff here
    });
}(currentIndex));