0

所以我正在尝试使用 Durandal 构建一个移动应用程序。但是,我在使用 Google plus JS API 集成时遇到了麻烦。我认为这是问题所在:gapi 的 javascript 客户端带有异步加载,因此 durandal 初始化会在 gapi 未定义的情况下崩溃,因此,css 组件也无法正确呈现。我已经尝试将以下脚本标签放在我的 login.js 视图的 login.html 文件中,甚至放在我的 main.js 的 require.js 部分中,但它仍然无法正常工作。用于链接到 Google 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>

有没有人尝试过将 google plus 登录与 Durandal 集成并遇到同样的问题?非常感谢帮助和建议!

4

2 回答 2

1

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

例如,以下是我们为 Google 地图所做的事情:

在RequireJS的paths属性中(通常在Durandal的main.js文件中),顺序如下:

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

定义,也在 Durandal 的 main.js 文件中,就在启动应用程序的 main 函数之前:

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) {

请注意async!远程 API URL 之前的内容。另请注意,我们实际上并没有为应用程序的主入口点定义 gmap。我们在主入口点之前设置了一个全局定义。

请让我知道这是否有帮助。

于 2015-01-20T21:50:52.460 回答
1

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

在 Google Plus Sign In 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;
    });

然后,您可以在您的特定视图模型中调用 gapi,方法是将其包含在视图模型的定义部分中。要实现google plus登录,您可以在定义并传入参数后调用以下函数,如Google Plus Sign in Javascript API(https://developers.google.com/+/web/signin )中的说明/javascript 流):

    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 方法绑定到我的 google 登录按钮 data-bind="click:googlelogin"。这将让您在单击按钮后使用您的 google plus 登录。但是,当涉及到我的回调时,这种方法似乎有问题。所以这是对我有用的第二种选择,当你的登录按钮被点击时,使用以下方法来授权用户并执行回调(你必须定义这个):

gapi.auth.authorize(parameters,signinCallBack);

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

于 2015-01-21T20:12:16.027 回答