如何在AngularJS或Javascript中实现与C#相似的东西?

时间:2015-10-01 14:06:09

标签: javascript c# angularjs

我正在开展一个项目,要求我让我的用户使用Google登录,我正在使用Google API客户端(可以找到here的参考资料。)

现在我的代码是这样的。

文件:services / auth-service.js

angular.module('myApp')
  .factory('gapi', function ($q) {

    var auth2;

    gapi.load('auth2', function () {
      auth2 = gapi.auth2.init({
        client_id: '649922003965-ni9e6nad25dh3ejoll70va550kt7cu5u.apps.googleusercontent.com'
      });
    });

    return {
      isSignedIn: function () {
        return auth2.isSignedIn.get();
      }
    }
  });

文件:controllers / dashboard.js

angular.module('myApp')
  .controller('DashboardCtrl', function (gapi) {
      alert(gapi.isSignedIn());
  });

现在问题是,当在dashboard.js文件中运行alert()命令时,到那时auth2还没有加载(因为它是通过互联网从Google API加载的)我因此得到一个错误isSignedIn不能被取消定义。

所以我理想情况下需要的是C#等待函数,它等待返回值并调用它的方法。任何解决方案都会非常感激。我花了好几个小时尝试承诺和其他方法,但我无法让它们中的任何一个工作。

更新: 您的大多数答案都适用于上述场景。让我们试试这个更复杂的场景,首先应该提到它。 (对不起)。

文件:scripts / app.js

.state('main', {
   url: '/admin',
   abstract: 'true',
   templateUrl: 'views/main.html',
   resolve: {
     check: function ($q, auth) {
       if(!auth.isSignedIn())
       {
          $q.reject({authenticated: 'false'});
       }
     }
   }
 })
 .state('admin', {
   url: '',
   parent: 'main',
   templateUrl: 'views/admin.html'
 })

现在,如果我在这里使用promises,angular将不会等待承诺得到解决。它将简单地加载视图并在加载视图后调用$ q.reject是没有用的。

3 个答案:

答案 0 :(得分:3)

您可以通过这种方式使用承诺来实现这一目标:

文件:services / auth-service.js

angular.module('myApp')
  .factory('gapi', function ($q) {

    var auth2;
    var isSignedInDeferred = $q.defer();

    gapi.load('auth2', function () {
      auth2 = gapi.auth2.init({
        client_id: '649922003965-ni9e6nad25dh3ejoll70va550kt7cu5u.apps.googleusercontent.com'
      });
      isSignedInDeferred.resolve(auth2.isSignedIn.get());
    });

    return {
      isSignedIn: function () {
        return isSignedInDeferred.promise;
      }
    }
  });

文件:controllers / dashboard.js

angular.module('myApp')
  .controller('DashboardCtrl', function (gapi) {
      gapi.isSignedIn().then(isSigned) {
          alert(isSigned);
      }
  });

只需更改isSignedIn函数即可返回promise并在获得值时解析该promise。

答案 1 :(得分:2)

该功能适用​​于ES7的草稿,如果您对此感到满意,babel(转换程序)支持async/await。话虽如此,只需承诺即可轻松完成:

gapi.client.load(name, version, callback)
  

将客户端库接口加载到特定API。 如果是回调   未提供,承诺退回。加载的API接口将   采用gapi.client.api.collection.method的形式。例如,   主持人API会创建类似的方法   gapi.client.moderator.series.list。

api已经给你一个承诺,所以不需要把它包裹在q,所有你需要做的就是回复这个承诺:

return gapi.load('auth2').then(function() {
    return gapi.auth2.init({
       client_id: '649922003965-ni9e6nad25dh3ejoll70va550kt7cu5u.apps.googleusercontent.com'
    });
});

现在,从您的控制器:

gapi.then(function(auth2){
  //auth2 already loaded
});

编辑:假设您可以在支票功能上获得退回的承诺。您所需要的只是:

var possiblyRejectedPromise = gapi.then(function(auth2){
   if(!auth2.isSignedIn.get()){
       throw new Error('Not logged in');
   } else {
       //LoggedIn
       return true;
   }
 });
return possiblyRejectedPromise;

答案 2 :(得分:0)

ES5中没有等同于TraCIMobility的内容。您需要深入了解事件发生时的处理方式,并根据这些事件更新应用程序状态。

对于您的具体问题,我认为您的假设是正确的是正确的,因为await变量尚未设置(因此未定义)。 " auth2 undefined" state是您的代码需要处理的应用程序状态之一。解决方案可能就像更改auth2函数一样简单:

isSignedIn

这样,只有在isSignedIn: function () { return auth2 && auth2.isSignedIn.get(); } 变量设置且auth2属性为真时,它才会返回true。