2014-01-22 66 views
3

我的控制器中有一个将用户添加到组的功能,一旦用户被分配到一个组,可用组的列表应该减少。我尝试使用函数中的promise来控制流,但是基于控制台日志,我的所有groupServices都先运行,然后userServices在运行,防止可用组列表更新校正。承诺没有按顺序运行

控制器功能:

$scope.addUserToGroup = function(){ 
     var defer = $q.defer(); 
     defer.promise.then(function(){ 
      userService.addUserToGroup(
       $scope.selectedUser, 
       $scope.selectedAvailableGroups, 
       $scope.assignedGroups, 
       $scope.availableGroups, 
       $scope.groups 
      ); 
     }).then(compare()); 
     defer.resolve(); 
    }; 
    function compare(){ 
    console.log('comparing assigned with all '); 
     $scope.compareGroups = groupService.compareGroups();   
    } 

我使用的承诺设法使为了在我的控制台运行输出而是根据一定的东西它似乎并不如此。

用户服务功能

var addUserToGroup = function (selectedUser, selectedAvailableGroups, assignedGroups, availableGroups, groups){ 

    console.dir(selectedUser); 
    console.dir(selectedAvailableGroups); 
    console.dir(assignedGroups); 
    console.dir(availableGroups); 
    console.dir(groups); 

    var deferred = $q.defer(); 

    var addPromise = []; 
    var selectLength = selectedAvailableGroups.length; 

    //Add user to selected groups on server 
    deferred.promise 
     .then(function(){ 
     for (var i = 0; i < selectLength; i++){ 
      addPromise[i] = $().SPServices({ 
      operation: "AddUserToGroup", 
      groupName: selectedAvailableGroups[i].name, 
      userLoginName: selectedUser.domain 
      });  
     }; 
     }) 
     .then(function(){ 
      //when promise finished, push changes to availableGroups 
      for (var i = 0; i < selectLength; i++){ 
      assignedGroups.push(selectedAvailableGroups[i]); 
      console.log(selectedUser.name + " added to: " + selectedAvailableGroups[i].name); 
      }; 
     }); 
    //Run 
    deferred.resolve(); 
    } 

组服务功能:

var compareGroups = function() { 
    //Comparing assigned groups with allGroups to return available groups 
    var assignedGroupsIds = {}; 
    var groupsIds = {}; 
    var result = [] 
    availableGroups = []; 
    console.log('assigned'); 
    console.dir(assignedGroups); 
    console.log('avail'); 

    assignedGroups.forEach(function (el, i) { 
     assignedGroupsIds[el.id] = assignedGroups[i]; 
    }); 

    allGroups.forEach(function (el, i) { 
     groupsIds[el.id] = allGroups[i]; 
    }); 

    for (var i in groupsIds) { 
     if (!assignedGroupsIds.hasOwnProperty(i)) { 
      result.push(groupsIds[i]); 
      availableGroups.push(groupsIds[i]); 

     } 
    }; 
    console.dir(result); 
    console.dir(availableGroups); 
} 

控制台登录:

comparing assigned with all userCtrl.js:47 
assigned groups    groupServices.js:63 
Array[8]     groupServices.js:64 
available gruops   groupServices.js:65 
Array[3]     groupServices.js:82 
Array[3]     groupServices.js:83 
Object      userServices.js:38 
Array[1]     userServices.js:39 
Array[8]     userServices.js:40 
Array[4]     userServices.js:41 
Array[11]     userServices.js:42 
User added to: Test Group 4 userServices.js:64 

回答

5

您正在使用错误的方式承诺。

第一个问题是在这里:

}).then(compare());

您尝试注册compare功能的执行结果作为回调,而不是注册只是compare功能是这样的:

}).then(compare);

这就是为什么它首先执行,然后调用groupService.compareGroups(),并且只有在它完成后,您才打电话给defer.resolve()和您的第一个注册回调执行。这就是为什么你看到你当前的控制台输出。

您需要修改用户服务及控制器在下列方式让它正常工作(使用$q服务与承诺工作):

控制器功能:

function compare(){ 
    console.log('comparing assigned with all '); 
    $scope.compareGroups = groupService.compareGroups();   
} 

$scope.addUserToGroup = function(){ 
    userService.addUserToGroup(
     $scope.selectedUser, 
     $scope.selectedAvailableGroups, 
     $scope.assignedGroups, 
     $scope.availableGroups, 
     $scope.groups 
    ).then(compare); 
}; 

用户服务功能:

(假设,$().SPServices返回Promise)

var addUserToGroup = function (selectedUser, selectedAvailableGroups, assignedGroups, availableGroups, groups){ 

    console.dir(selectedUser); 
    console.dir(selectedAvailableGroups); 
    console.dir(assignedGroups); 
    console.dir(availableGroups); 
    console.dir(groups); 

    var deferred = $q.defer(); 

    var addPromise = []; 
    var selectLength = selectedAvailableGroups.length; 

    //Add user to selected groups on server 
    for (var i = 0; i < selectLength; i++){ 
     addPromise[i] = $().SPServices({ 
      operation: "AddUserToGroup", 
      groupName: selectedAvailableGroups[i].name, 
      userLoginName: selectedUser.domain 
     });  
    } 

    $q.all(addPromise).then(function(){ 
     //when promise finished, push changes to availableGroups 
     for (var i = 0; i < selectLength; i++){ 
      assignedGroups.push(selectedAvailableGroups[i]); 
      console.log(selectedUser.name + " added to: " + selectedAvailableGroups[i].name); 
     }; 

     //Finish function 
     deferred.resolve(); 
    }); 
    return deferred.promise; 
} 
+0

嗨安德烈,我已经实现了你的改变,但现在整个事情比以前运行慢很多。另外,当比较运行并调整可用组时,现在它会返回正确的组数,但DOM不会更新以反映更改。 – Batman

+0

@Batman您使用的是哪个版本的AngularJs和Promises Api的实现?你能提供你实施的小提琴吗? –

+0

我会把我的项目推到github上。应该给你一个完整的图片。给我一秒钟。 – Batman