在函数内调用函数(Javascript) [英] calling function within a function (Javascript)

查看:88
本文介绍了在函数内调用函数(Javascript)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简而言之,我希望在单击此按钮时执行以下功能:

In a nutshell, I want the following function to be executed when this button is clicked:

<input type="button" value="upload" onclick="generateUpload();" />

但是它似乎没有响应,我从控制台收到零错误.

But it does not seem to be responding and I receive zero error from console.

下面是generateUpload()函数,我知道该函数内部的功能是有效的,因为我试图用它加载页面,并且Google驱动器选择器将运行,但我只希望它在单击按钮时运行.

Below is the generateUpload() function, and I know whats inside that function works because I have tried to load the pages with it and the google drive picker would run but I only want it to run upon button click.

<script type="text/javascript" src="https://apis.google.com/js/api.js?onload=onApiLoad"></script>

<script type="text/javascript">
function generateUpload() 
{

   // The Browser API key obtained from the Google Developers Console.
      var developerKey = 'id';

      // The Client ID obtained from the Google Developers Console.
      var clientId = 'id';

      // Scope to use to access user's photos.
      var scope = ['https://www.googleapis.com/auth/photos'];

      var pickerApiLoaded = false;
      var oauthToken;

      // Use the API Loader script to load google.picker and gapi.auth.
      function onApiLoad() {
        gapi.load('auth', {'callback': onAuthApiLoad});
        gapi.load('picker', {'callback': onPickerApiLoad});
      }

      function onAuthApiLoad() {
        window.gapi.auth.authorize(
            {
              'client_id': clientId,
              'scope': scope,

              'immediate': true
            },
            handleAuthResult);
      }

      function onPickerApiLoad() {
        pickerApiLoaded = true;
        createPicker();
      }

      function handleAuthResult(authResult) {
        if (authResult && !authResult.error) {
          oauthToken = authResult.access_token;
          createPicker();
        }
      }

      // Create and render a Picker object for picking user Photos.
      function createPicker() {
        if (pickerApiLoaded && oauthToken) {
          var picker = new google.picker.PickerBuilder().
              enableFeature(google.picker.Feature.MULTISELECT_ENABLED).
              addView(google.picker.ViewId.PDFS).
              setOAuthToken(oauthToken).
              setDeveloperKey(developerKey).
              setCallback(pickerCallback).
              build();
          picker.setVisible(true);
        }
      }

      // A simple callback implementation.
      function pickerCallback(data) {
        var url = 'nothing';
        if (data[google.picker.Response.ACTION] == google.picker.Action.PICKED) {
          var doc = data[google.picker.Response.DOCUMENTS][0];
          url = doc[google.picker.Document.URL];
                 var message = 'The following(s) were stored in Parse: ' + url;
        document.getElementById('result').innerHTML = message;

        }
      }
}
</script>

下面是在正文中找到的按钮:

Below is the button found in the body:

<input type="button" value="Create Short" onclick="generateUpload();" /> <br/> 

更新: 下面是完整的代码:

Update: below is the entire code:

<!DOCTYPE html>
<html>
<head>
<script src="http://www.parsecdn.com/js/parse-1.2.12.min.js"></script>

  <script src="angular.js"></script>
    <link href="css/bootstrap.min.css" rel="stylesheet">
<!--======================================================================-->
<!--Custom website css file is linked here-->
<link href="css/style1.css" rel="stylesheet">
<!--Font Awesome CSS link-->
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">



   <script>
   Parse.initialize("ID", "ID");



var module = angular.module("AuthApp", []);
module.controller("MyCntrl", function($scope) {
      $scope.currentUser = Parse.User.current();

   $scope.userIdChanged = function () {
       $scope.loading = true;

       // now access $scope.userId here
       var query = new Parse.Query(Parse.User);

       query.get($scope.userId, {
           success: function(userInfo) {
               // The object was retrieved successfully.
               var address = userInfo.get("Address");
               $scope.address = 'address: ' + address;

               var email = userInfo.get("Email");
               $scope.email = 'Email: ' + email;


                    var phone = userInfo.get("Phone");
               $scope.phone = 'Phone: ' + phone;

                 var scanURL = '<a href="scan.html">Scan</a>';
               $scope.scanURL = scanURL;
                          $scope.loading = false;


           },
           error: function(object, error) {
               // The object was not retrieved successfully.
               // error is a Parse.Error with an error code and message.
                          $scope.loading = false;

           }
       });
   };
});
</script>

     <script type="text/javascript" src="https://apis.google.com/js/api.js?onload=onApiLoad"></script>

<script type="text/javascript">
function generateUpload() 
{

    // The Browser API key obtained from the Google Developers Console.
      var developerKey = 'ID';

      // The Client ID obtained from the Google Developers Console.
      var clientId = 'ID';

      // Scope to use to access user's photos.
      var scope = ['https://www.googleapis.com/auth/photos'];

      var pickerApiLoaded = false;
      var oauthToken;

      // Use the API Loader script to load google.picker and gapi.auth.
      function onApiLoad() {
        gapi.load('auth', {'callback': onAuthApiLoad});
        gapi.load('picker', {'callback': onPickerApiLoad});
      }

      function onAuthApiLoad() {
        window.gapi.auth.authorize(
            {
              'client_id': clientId,
              'scope': scope,

              'immediate': true
            },
            handleAuthResult);
      }

      function onPickerApiLoad() {
        pickerApiLoaded = true;
        createPicker();
      }

      function handleAuthResult(authResult) {
        if (authResult && !authResult.error) {
          oauthToken = authResult.access_token;
          createPicker();
        }
      }

      // Create and render a Picker object for picking user Photos.
      function createPicker() {
        if (pickerApiLoaded && oauthToken) {
          var picker = new google.picker.PickerBuilder().
              enableFeature(google.picker.Feature.MULTISELECT_ENABLED).
              addView(google.picker.ViewId.PDFS).
              setOAuthToken(oauthToken).
              setDeveloperKey(developerKey).
              setCallback(pickerCallback).
              build();
          picker.setVisible(true);
        }
      }

      // A simple callback implementation.
      function pickerCallback(data) {
        var url = 'nothing';
        if (data[google.picker.Response.ACTION] == google.picker.Action.PICKED) {
          var doc = data[google.picker.Response.DOCUMENTS][0];
          url = doc[google.picker.Document.URL];
                 var message = 'The following(s) were stored in Parse: ' + url;
        document.getElementById('result').innerHTML = message;

        }
      }

      addOnOnApiLoadedCallback(onApiLoad); // register API load
}

var gapi_loaded = false, gapi_buffered_callbacks = [];
function onApiLoad() { // this function gets called by the Google API
    gapi_loaded = true;
    // run buffered callbacks
    for (var i = 0; i < gapi_buffered_callbacks.length; i += 1) {
        gapi_buffered_callbacks();
    }
}
function addOnOnApiLoadedCallback(callback) {
    if (gapi_loaded) {
        callback(); // api is loaded, call immediately
    } else {
        gapi_buffered_callbacks.push(callback); // add to callback list
    }

}

</script>

</head>
<body ng-app="AuthApp">


<div>
    <div class="row row-centered">
        <div class="col-xs- col-centered col-fixed"><div class="item"><div class="content">
    <div ng-controller="MyCntrl">
          <div ng-show="currentUser">
             <div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
      <div class="container">
        <div class="navbar-header">

                    <div id="navbar" class="navbar-collapse collapse">

            <h2> Admin Panel </h2>
          </div></div></div></div>


                    <div id="content">


            <h3> Upload a new user document </h3>

        <h4><b> Step 1: <input type="text" class="form-control" ng-model="userId" ng-blur="userIdChanged()"/>

            <div>{{email}}</div>

                 <br />

                        <input type="text" id="subjectP" placeholder="Subject line">
<textarea cols="50" rows="4" name="comment" id="notesP" placeholder="notes"></textarea>


<br />
        <h4><b> Step 2</b></h4>
                                <input type="button" value="Create Short" onclick="generateUpload();" /> <br/> <br/>


<div id="result"></div>



</div></div></div></div>

</div>
            </div>
    </body>
</html>

推荐答案

我想我明白了.您已将Google API设置为在加载完成后调用onApiLoad.但是该函数在全局范围中不存在,因此会出现错误.

I think I get it. You've set up the google API to call onApiLoad when it's finished loading. But that function doesn't exist in the global scope so you'll get an error.

棘手的部分是,当您单击按钮 且Google API已完成加载时,您要运行代码.

The tricky part is that you want to run your code when you click your button and the google API has finished loading.

有两种方法可以解决此问题:

There are two ways to approach this:

1)在Google API完成加载之前,请不要渲染按钮.这涉及在您的onApiLoad函数中呈现(或显示)按钮.

1) Don't render the button until the Google API has finished loading. This involves rendering (or making visible) the button in you onApiLoad function.

由于UI/UX的原因,这可能不可行,因此有一个更复杂的解决方案:

That might not be feasible because of UI/UX stuff so there is a more complex solution:

2)为onApiLoad事件编写处理程序:

2) Write a handler for the onApiLoad event:

var gapi_loaded = false, gapi_buffered_callbacks = [];
function onApiLoad() { // this function gets called by the Google API
    gapi_loaded = true;
    // run buffered callbacks
    for (var i = 0; i < gapi_buffered_callbacks.length; i += 1) {
        gapi_buffered_callbacks();
    }
}
function addOnOnApiLoadedCallback(callback) {
    if (gapi_loaded) {
        callback(); // api is loaded, call immediately
    } else {
        gapi_buffered_callbacks.push(callback); // add to callback list
    }
}

然后在generateUpload函数内部添加:

addOnOnApiLoadedCallback(onApiLoad);


现在您可以看到,这需要大量的簿记.已经提出了使此变得更容易的想法. Promises是其中之一.如果您想探索更多,我建议您从这里开始.


Now as you can see this requires quite a bit of bookkeeping. Ideas have been developed to make this easier. Promises are one of them. If you want to explore more I suggest you start there.

这是完整的代码:

function generateUpload() 
{

   // The Browser API key obtained from the Google Developers Console.
      var developerKey = 'id';

      // The Client ID obtained from the Google Developers Console.
      var clientId = 'id';

      // Scope to use to access user's photos.
      var scope = ['https://www.googleapis.com/auth/photos'];

      var pickerApiLoaded = false;
      var oauthToken;

      // Use the API Loader script to load google.picker and gapi.auth.
      function onApiLoad() {
        gapi.load('auth', {'callback': onAuthApiLoad});
        gapi.load('picker', {'callback': onPickerApiLoad});
      }

      function onAuthApiLoad() {
        window.gapi.auth.authorize(
            {
              'client_id': clientId,
              'scope': scope,

              'immediate': true
            },
            handleAuthResult);
      }

      function onPickerApiLoad() {
        pickerApiLoaded = true;
        createPicker();
      }

      function handleAuthResult(authResult) {
        if (authResult && !authResult.error) {
          oauthToken = authResult.access_token;
          createPicker();
        }
      }

      // Create and render a Picker object for picking user Photos.
      function createPicker() {
        if (pickerApiLoaded && oauthToken) {
          var picker = new google.picker.PickerBuilder().
              enableFeature(google.picker.Feature.MULTISELECT_ENABLED).
              addView(google.picker.ViewId.PDFS).
              setOAuthToken(oauthToken).
              setDeveloperKey(developerKey).
              setCallback(pickerCallback).
              build();
          picker.setVisible(true);
        }
      }

      // A simple callback implementation.
      function pickerCallback(data) {
        var url = 'nothing';
        if (data[google.picker.Response.ACTION] == google.picker.Action.PICKED) {
          var doc = data[google.picker.Response.DOCUMENTS][0];
          url = doc[google.picker.Document.URL];
                 var message = 'The following(s) were stored in Parse: ' + url;
        document.getElementById('result').innerHTML = message;

        }
      }

      addOnOnApiLoadedCallback(onApiLoad); // register API load
}

var gapi_loaded = false, gapi_buffered_callbacks = [];
function onApiLoad() { // this function gets called by the Google API
    gapi_loaded = true;
    // run buffered callbacks
    for (var i = 0; i < gapi_buffered_callbacks.length; i += 1) {
        gapi_buffered_callbacks();
    }
}
function addOnOnApiLoadedCallback(callback) {
    if (gapi_loaded) {
        callback(); // api is loaded, call immediately
    } else {
        gapi_buffered_callbacks.push(callback); // add to callback list
    }
}

这篇关于在函数内调用函数(Javascript)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆