AngularJS ng-click和回调函数

时间:2014-02-27 14:26:53

标签: javascript ajax angularjs asynchronous

在我的网络应用程序中,有两种用户:来宾&登录。主页面为每个页面加载相同的内容。

我的目标:

  • 当注册用户点击链接时,会检索2个ajax请求($ http) 另一个页面的数据并将它们加载到模型中。
  • 如果用户是访客,则会出现另一个模型,说他必须注册。

我的链接:

<h4 ng-click="guestAction($event, showOne($event,card.id));">click me</h4>

GuestAction:

$scope.guestAction = function($event, callbackB) {

    $http.get('/guest/is-guest/').success(function(data) {
        console.log("isGuest retrieved : " + data);
        if (data == 1)
        {
            alert('guest spotted !');
            return false;
        }
        else
        {
            alert('user');
            console.log(callbackB);
            eval('$scope.'+callbackB);
        }

    });

}

这样,如果发现了guest,我们返回false并停止执行。如果它是普通用户,我们执行showOne函数。由于我想一个接一个地做2个异步请求,我选择使用回调技巧。

问题是当启动ng-click时会直接执行showOne()。我尝试将showOne()作为字符串传递,eval()将字符串传递给GuestAction,但参数变为未定义...

知道如何解决这个问题吗?我想使用一个泛型方法,只有在用户被记录时才会触发函数。

2 个答案:

答案 0 :(得分:6)

我建议使用服务和承诺see this AngularJS $q

您不必为$ http请求使用服务,但这只是我的偏好,它使您的控制器更清洁

这是承诺的服务:

app.factory('myService', function ($http, $q) {

    var service = {};

    service.guestAction = function () {
        var deferred = $q.defer();
        $http.get('/guest/is-guest/').success(function(data) {
            console.log("isGuest retrieved : " + data);
            if (data == 1) {
                deferred.resolve(true);
            } else {
                deferred.resolve(false);
            }
        }).error(function (data) {
            deferred.reject('Error checking server.');
        });
        return deferred.promise;
    };

    return service;
});

然后在我们的控制器中我们称之为:

app.controller('myController', function ($scope, myService) {

    $scope.guestAction = function($event, card) {
        myService.guestAction().then(function (data) {
            if (data) {
                alert('guest spotted !');
            } else {
                alert('user');
                // Then run your showOne
                // If this is also async I would use another promise
                $scope.showOne($event, card.id);
            }
        }, function (error) {
            console.error('ERROR: ' + error);
        })
    };
});

现在很明显你可能不得不在这里和那里改变它以使它满足你的需求,但承诺做的是允许你执行代码,一旦承诺被返回然后继续,我相信这样的东西就是你正在寻找的对

答案 1 :(得分:2)

您必须将函数作为参数传递而不使用括号,并分别传递参数:

<h4 ng-click="guestAction($event,card.id, showOne);">click me</h4>

$scope.guestAction = function($event,id, callbackB) {

    $http.get('/guest/is-guest/').success(function(data) {
        console.log("isGuest retrieved : " + data);
        if (data == 1)
        {
            alert('guest spotted !');
            return false;
        }
        else
        {
            alert('user');
            callbackB($event,id);
        }

    });

}