2015-01-20 151 views
0

所以我试图建立一个使用Durandal的移动应用程序。但是,使用Google plus JS API集成时,我遇到了麻烦。我认为这是问题:gapi的javascript客户端带有异步加载,所以durandal初始化会在gapi未定义时崩溃,因此,css组件也不能正确呈现。我曾尝试将以下脚本标记放在我的view.js的login.html文件中,甚至在我的main.js的require.js部分中,但它仍然不起作用。链接到谷歌阿比脚本:Durandal JS和谷歌加登录JavaScript API

<script src="https://apis.google.com/js/client:platform.js" async defer> </script> 
<script src="https://apis.google.com/js/platform.js?onload=onLoadCallback" async defer></script> 

//onSignInCallBack function to call in login.js after user signs in vis Google Plus 
onSignInCallback: function(authResult) { 
        gapi.client.load('plus','v1').then(function() { 

         if (authResult['access_token']) { 
          $('#authOps').show('slow'); 
          $('#gConnect').hide(); 
          var user_access_token = authResult['access_token']; 
          var id_token = authResult['id_token']; 
         } else if (authResult['error']) { 
          // There was an error, which means the user is not signed in. 
          console.log('There was an error: ' + authResult['error']); 
          $('#authOps').hide('slow'); 
          $('#gConnect').show(); 
         } 
         console.log('authResult', authResult); 
        }); 
       }, 

这是我main.js文件:

requirejs.config({ 
    paths: { 
     'text': '../Scripts/text', 
     'durandal': '../Scripts/durandal', 
     'plugins': '../Scripts/durandal/plugins', 
     'transitions': '../Scripts/durandal/transitions', 
     'knockout' : '../Scripts/knockout-3.1.0', 
     'bootstrap': '../Scripts/bootstrap', 
     'jquery':'../Scripts/jquery-1.9.1', 
     'async':'../Scripts/async' 
    } 
}); 


define(['durandal/system', 
     'durandal/app', 
     'durandal/viewLocator', 
     'durandal/binder', 
     'utils/routines', 
     'async!https://apis.google.com/js/platform.js?onload=onLoadCallback', 
     'async!https://apis.google.com/js/client:platform.js' 

], function (system, app, viewLocator, binder,routines,callback,gapi) { 

    //>>excludeStart("build", true); 
    system.debug(true); 
    //>>excludeEnd("build"); 

    app.configurePlugins({ 
     router: true, 
     dialog: true, 
     widget: true 
    }); 

    app.start().then(function() { 
     //Replace 'viewmodels' in the moduleId with 'views' to locate the view. 
     //Look for partial views in a 'views' folder in the root. 
     viewLocator.useConvention(); 

     //Show the app by setting the root view model for our application with a transition. 
     app.setRoot('shell/shell', 'entrance'); 

     // override bad route behavior to write to 
     // console log and show error toast 
     /* 
     router.handleInvalidRoute = function (route, params) { 
      logger.logError('No route found', route, 'main', true); 
     }; 
     */ 
    }); 
}); 

这里是我的index.html:

<!DOCTYPE html> 
<html> 
<head> 

    <meta charset="utf-8" /> 
    <meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1" /> 
    <meta name="apple-mobile-web-app-capable" content="yes" /> 
    <meta name="apple-mobile-web-app-status-bar-style" content="black" /> 
    <meta name="format-detection" content="telephone=no" /> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 

    <link rel="apple-touch-startup-image" href="/Content/images/ios-startup-image- landscape.png" media="(orientation:landscape)" /> 
    <link rel="apple-touch-startup-image" href="/Content/images/ios-startup-image-portrait.png" media="(orientation:portrait)" /> 
    <link rel="apple-touch-icon" href="~/Content/images/icon.png" /> 
    <link href="/Content/ie10mobile.css" rel="stylesheet" /> 
    <link href="/Content/bootstrap.min.css" rel="stylesheet" /> 
    <link href="/Content/font-awesome.min.css" rel="stylesheet" /> 
    <link href="/Content/durandal.css" rel="stylesheet" /> 
    <link href="/Content/starterkit.css" rel="stylesheet" /> 

    <script type="text/javascript"> 

     if (navigator.userAgent.match(/IEMobile\/10\.0/)) { 
      var msViewportStyle = document.createElement("style"); 
      var mq = "@@-ms-viewport{width:auto!important}"; 
      msViewportStyle.appendChild(document.createTextNode(mq)); 
      document.getElementsByTagName("head")[0].appendChild(msViewportStyle); 
     } 
    </script> 
</head> 
<body> 
    <div id="applicationHost"> 
     <div class="text-center"> 
      <br/><br/><br/><br/> 
      <i class="fa fa-spinner fa-spin"></i> 
      <div class="message"> 
       Loading.... 
      </div> 
     </div> 
    </div> 
    <script type="text/javascript" src="Scripts/require.js" data-main="/App/main"></script> 

</body> 
</html> 

有没有人试过整合谷歌加上用Durandal登录并且有同样的问题?帮助和建议非常感谢!

+0

就这么你知道,除了你的初始页面以外的任何页面上的脚本标签都被忽略。 – 2015-01-20 20:16:57

+0

是的,这是我的想法,但我找不到任何其他方式。因此,如果我试图通过调用url加载API,那么在Durandal中做到这一点的最佳方式是什么?我是否仍然可以将URL链接到我链接到其他脚本的主要部分的require.js部分中?谢谢Eric! – 2015-01-20 20:59:08

+0

此外,我使用的Facebook sdk JavaScript异步加载,它工作正常,但不适用于谷歌加javascript api。 – 2015-01-20 21:08:27

回答

1

对于Durandal(或换句话说,在RequireJS下)的远程异步加载,您需要异步,goog和propertyParser plugins。请参阅该链接的自述文件。

作为一个例子,这里是我们为谷歌地图做到:

在RequireJS(通常在迪朗达尔的main.js文件)的路径属性的,顺序如下:

'async': '../Scripts/plugins/async', 
'propertyParser': '../Scripts/plugins/propertyParser', 
'goog': '../Scripts/plugins/goog' 

的定义,也迪朗达尔的main.js文件,只需揭开序幕应用程序的主函数之前:

define('jquery', function() { return jQuery; }); 
define('knockout', ko); 
define('gmaps', ['async!http://maps.google.com/maps/api/js?sensor=false'], 
    function() {    
     return window.google.maps; 
    }); 

define(['durandal/system', 
     'durandal/app', 
     'durandal/viewLocator', 
     'bindings', 
     'extenders', 
     'validations'], 
    function (system, app, viewLocator, bindings, extenders, validations) { 

注意远程API URL之前的async!。另外请注意,我们实际上并没有为应用程序的主入口点定义gmaps。我们在之前成立了全球定义的主要切入点。

请让我知道,如果有帮助。

+0

@KendrickLay你可以发布你的main.js和index.html(或任何你的默认页面)?谢谢。 – 2015-01-21 02:14:46

+0

@KendrickLay O.K.我对此做了更多的研究。就像我们为Google Maps API所做的那样,您将需要两个额外的插件:** goog **插件和** propertyParser **插件。我认为那些只是Google地图所必需的。我会更新我的答案。 – 2015-01-21 03:26:40

+0

@KenrickLay看看你的'定义'。我更新了代码,告诉你他们会去哪里,这使得它们可以在整个应用程序中全局注入。至于您使用的API的具体情况,我无法真正帮助您。你可能需要为你正在使用的API使用'goog!'前缀。另外,您可能需要返回全局窗口参考,就像我们使用Google地图一样。这些插件的论坛可能是发布问题的最佳地点。只是你知道,这是混乱的生意。但它确实可靠地工作... – 2015-01-21 03:38:24

1

所以我找到了解决方案,将谷歌加号登录到我的Durandal应用程序中。您基本上需要包含asyncJS(不必包含googJS/propertyParserJS,goog仅适用于非常特定的Google API - (https://developers.google.com/loader/?csw=1#AvailableAPIs),位于main.js的require部分,并在main.js中定义google客户端api。但是,你不能使用以下URL来调用API中的定义main.js.

<script src="https://apis.google.com/js/client:platform.js" async defer> </script> 
<script src="https://apis.google.com/js/platform.js?onload=onLoadCallback" async defer></script> 

在谷歌加号的Javascript API文档,你被要求包含在HTML文件上面的脚本标签。但是,这不适用于requireJS和Async,而需要调用Google Client API并在main.js中使用以下url:

 define('gapi',['async!https://apis.google.com/js/client.js!onload'], function() { 
     console.log('gapi loaded: ' + gapi); 
     return window.gapi; 
    }); 

然后,您可以通过在viewmodel的define部分中包含它来调用gapi在特定的viewmodel中。为了实现谷歌加登录,就可以调用下面的函数定义和传递如在Javascript API在谷歌加号指令中规定的参数后(https://developers.google.com/+/web/signin/javascript-flow):

define(['gapi'], function(gapi) { 
    return { 
     additionalParams : { 
      'callback': "specify a callback function here", 
      'clientid' :"your client_ID", 
      'scope' : "scope for permissions", 
      'cookiepolicy' : "single_host_origin" 
      }, 


      googlelogin: function() { 
       gapi.auth.signIn(this.additionalParams); 
      } 
    } 
    }); 

我然后绑定的GoogleLogin方法到我的谷歌登录按钮使用 data-bind="click:googlelogin"。这会让你在点击按钮后使用你的谷歌加号登录。但是,当涉及到我的回调时,这种方法似乎有问题。因此,这里是为我工作的第二个选择,用下面的方法对用户进行授权和执行回调(你必须定义这个)你的按钮标志被点击时:

gapi.auth.authorize(parameters,signinCallBack); 

的参数在此指定: (https://developers.google.com/api-client-library/javascript/reference/referencedocs#gapiauthauthorize)。希望这可以帮助您将Durandal/RequireJS应用程序与Google Plus和Ouath2集成到客户端JS实现中!谢谢@EricTaylor指导我!

+1

任何机会,您可以发布完整的main.js脚本。我已经添加了定义,但没有获取任何记录到控制台的内容。 – Luke 2015-05-19 19:42:28

+0

我试图实施reCaptcha,这似乎很有前途,但没有得到它正确的。如果您可以发布您的主Js或更好,但如果您已完成reCaptcha。谢谢 – mboko 2015-05-21 10:48:33

+0

如果您将回调函数直接传递到回调属性,如下所示,您可以使用gapi.auth.signIn方法: 'callback':onSignIn 如果您在示例中执行此操作('callback':“onSignIn”)它仅适用于全局回调函数。 – 2015-11-20 12:21:11