简体   繁体   English

使用then()调用其他两个函数:错误-无法调用未定义的方法“ then”

[英]Using then() to call two other functions : Error - Cannot call method “then” of undefined

Basically I have the function getUserInfo which has one function that returns available and assigned groups within the service. 基本上,我具有getUserInfo函数,该函数具有一个返回服务中可用组和已分配组的函数。 Then I have the other two functions below return those objects. 然后,我在下面的其他两个函数中返回了这些对象。 However, I can't run the getAssignedGroups() and getAvailableGroups() before the first function is done. 但是,在完成第一个功能之前,我无法运行getAssignedGroups()getAvailableGroups() So I thought I'd use the then() to ensure those two ran once the first function was completed. 因此,我认为我将使用then()来确保在第一个函数完成后运行这两个。

I have this function in a controller: 我在控制器中具有此功能:

$scope.getUserInfo = function(selectedUser) {
    $scope.userGroupInfo = groupService.getUserGroups(selectedUser.domain,$scope.groups).then(
        $scope.assignedGroups = groupService.getAssignedGroups(),
        $scope.availableGroups = groupService.getAvailableGroups()
    );
};

This is my service: 这是我的服务:

spApp.factory('groupService', function () {
    var assignedGroups, availableGroups, allGroups;

    var getGroups = function () {
        allGroups = [];

        $().SPServices({
            operation: "GetGroupCollectionFromSite",
            completefunc: function(xData, Status) {
                var response = $(xData.responseXML);
                response.find("Group").each(function() {
                    allGroups.push({
                        id: $(this).attr('ID'),
                        name: $(this).attr('Name'),
                        Description: $(this).attr('Description'),
                        owner: $(this).attr('OwnerID'),
                        OwnerIsUser: $(this).attr('OwnerIsUser'),
                    });
                }); 
            }
        });
        return allGroups;
    }
    var getUserGroups = function (selectedUser, allGroups) {
        assignedGroups = [];

        $().SPServices({
            operation: "GetGroupCollectionFromUser",
            userLoginName: selectedUser,
            completefunc: function(xData, Status) {

                var response = $(xData.responseXML);

                response.find("errorstring").each(function() {
                    alert("User not found");
                    booErr = "true";
                    return;
                });

                response.find("Group").each(function() {
                    assignedGroups.push({                       
                        id: $(this).attr('ID'),
                        name: $(this).attr('Name'),
                        Description: $(this).attr('Description'),
                        owner: $(this).attr('OwnerID'),
                        OwnerIsUser: $(this).attr('OwnerIsUser'),
                    });

                });
            }
        });

        //from here I start comparing All Groups with user groups to return available groups
        var assignedGroupsIds = {};
        var groupsIds = {};
        var availableGroups = [];

        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)) {
                availableGroups.push(groupsIds[i]);
            }
        }
/*      return {
            assignedGroups:assignedGroups,
            availableGroups:availableGroups
        }*/
    }
    var getAvailableGroups = function () {
        return availableGroups;
    }
    var getAssignedGroups = function () {
        return assignedGroups;
    };   

    return {
        getGroups:getGroups,
        getUserGroups:getUserGroups,
        getAvailableGroups: getAvailableGroups,
        getAssignedGroups:getAssignedGroups
    }
});

You can inject the Angular promise module into your factory: 您可以将Angular promise模块注入工厂:

spApp.factory('groupService', function ($q) {

Then inside the getUserGroups() function of your factory, declare a deferred object: 然后在工厂的getUserGroups()函数中,声明一个延迟的对象:

var deferred = $q.defer();

Then you need to use deferred.resolve(response) inside your async request and return deferred.promise from your function. 然后,您需要在异步请求中使用deferred.resolve(response)并从函数中返回deferred.promise Also, the then function takes a function with the returned response as the argument (so you can then access the response from the controller): 另外, then函数采用以返回的响应作为参数的函数(因此您可以从控制器访问响应):

$scope.userGroupInfo = groupService.getUserGroups(selectedUser.domain,$scope.groups).then(function(resp) {
    $scope.assignedGroups = groupService.getAssignedGroups(),
    $scope.availableGroups = groupService.getAvailableGroups()
});

Look into the AngularJS docs on $q for more info. 查看$ q上AngularJS文档以获取更多信息。

Better approach will be use callback approach. 更好的方法是使用回调方法。 You can take following approach. 您可以采用以下方法。

$scope.getUserInfo = function(selectedUser, getUserInfoCallback) {
    $scope.userGroupInfo = groupService.getUserGroups(selectedUser.domain,$scope.groups, function (response){
        $scope.assignedGroups = groupService.getAssignedGroups( function (response){
        $scope.availableGroups = groupService.getAvailableGroups( function(response){
            //Here call parent callback
            if(getUserInfoCallback)
            {
                getUserInfoCallback(response); //If you need response back then you can pass it.
            }
        })
        })

    })    
    );
};

Now you need to define each method as callback. 现在,您需要将每个方法定义为回调。 Following is sample method for your reference. 以下是示例方法供您参考。

$scope.getAssignedGroups = function (getAssignedGroupsCallback){

//Do all operation
//Now call callback
if(getAssignedGroupsCallback)
{
getAssignedGroups();//you can pass data here which you would like to get it return
}

};

Note: I have just added the code to clarify the approach. 注意:我刚刚添加了代码以阐明方法。 You need to change it to compile and implement your own logic. 您需要对其进行更改以编译和实现自己的逻辑。

Summary of approach : All services are invoked asynchronously therefore you need to pass callback method as chain (to keep your code clean) so that your code can wait for next step. 方法摘要 :所有服务都是异步调用的,因此您需要将回调方法作为链传递(以保持代码干净),以便您的代码可以等待下一步。

Hope it helps. 希望能帮助到你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM