将数据从服务传递到控制器

时间:2014-09-18 14:32:08

标签: javascript angularjs facebook-graph-api cordova-plugins

我有一个工厂将它传递给控制器​​LoginCtrl

.factory('Fbdata', function(){
    var service = {
        data: {
          apiData: []
        },
        login: function () {
            facebookConnectPlugin.login(["email"],
              function() {
            facebookConnectPlugin.api("me/?fields=id,email,name,picture", ["public_info","user_birthday"],
                function (results) {
                    service.data.apiData = results;
                    console.log(service.data.apiData);
                    return results;
                },
                function (error) {
                    console.error('FB:API', error);
                });
              },
               function(err) {
                console.error('FB:Login', err);
            });
        }
    };
    return service;
})

LoginCtrl:

.controller('LoginCtrl', function($scope, Fbdata){
    $scope.login = function(){
        if (!window.cordova) {
            var appId = "appId";
            facebookConnectPlugin.browserInit(appId);
        }

        $scope.loginData = Fbdata.login();
        console.log(Fbdata.data.apiData);
        // got empty array []
        $scope.retVal= angular.copy(Fbdata.data.apiData);
    };
})

Fbdata.data.apiData返回空数组,我只能在控制台中看到登录成功函数返回的数据。 我的模板有LoginCtrl作为控制器:

  <div class="event listening button" ng-click="login();">Login with Facebook</div>
    <h2>{{loginData.name}}</h2>
    <h2>{{retVal.name}}</h2>

1 个答案:

答案 0 :(得分:0)

有多种方法可以实现这一目标,例如:

现在我从未使用Cordova Facebook Plugin因此我不确定您是否需要在登录后运行api函数,或者需要如何订购这些过程。但我想向您展示如何使用您的代码示例从factory检索数据的示例。希望有所帮助


编辑2

我已经将我的代码更改为使用promises,这样我们确保在没有完成其他操作的情况下我们不会调用它,我不喜欢将loginapi函数链接在一起一个功能,因为可能(?)您可能需要致电login()但不想致电api(),请尝试我的代码并粘贴到问题底部的控制台日志中。

<强>工厂:

// Let's add promises to our factory using AngularJS $q
.factory('Fbdata', ['$q', function($q){
    // You could also just replace `var service =` with `return` but I thought this
    // would make it easier to understand whats going on here.
    var service = {
        // I generally nest result to keep it clean when I log
        // So results from functions that retrieve results are stored here
        data: {
            login: [],
            api: []
        },
        api: function() {
            var q = $q.defer();
            facebookConnectPlugin.api("me/?fields=id,email,name,picture", ["public_info","user_birthday"],
                function (results) {
                    // assign to the object being returned
                    service.data.api = results;
                    // The data has returned successfully so we will resolve our promise
                    q.resolve(results);
                },
                function (error) {
                    // We reject here so we can inform the user within through the error/reject callback
                    q.reject(error);
                    console.error('FB:API', error);
                });
            // Now that we have either resolved or rejected based on what we received
            // we will return the promise
            return q.promise;
        },
        login: function () {
            var q = $q.defer();
            facebookConnectPlugin.login(["email"], function (results) {
                // assign to the object being returned
                service.data.login = results;
                q.resolve(results);
            }, function(err) {
                q.reject(error);
                console.error('FB:Login', err);
            });
            return q.promise;
        }
    };
    return service;
}])

<强>控制器:

.controller('LoginCtrl', function($scope, Fbdata){
    $scope.login = function(){
        if (!window.cordova) {
            var appId = "appid";
            facebookConnectPlugin.browserInit(appId);
        }
        // By using the promises in our factory be can ensure that API is called after
        // login by doing the following

        // then(success, reject) function allows us to say once we have a return, do this.
        Fbdata.login().then(function () {
            $scope.loginData = Fbdata.data.login;
            // Check what was returned
            console.log('loginData', $scope.loginData);
            Fbdata.api().then(function () {
                $scope.apiData = Fbdata.data.api;
                console.log('apiData', $scope.apiData);
            }, function () {
                // Tell the user that the api failed, if necessary
            });
        }, function () {
            // Tell the user that the log in failed
        });
    };
});