前一页仅在有2页时才有效(Google Drive API)。

huangapple go评论83阅读模式
英文:

Why previous page only works if there's 2 pages (Google Drive API)

问题

Sure, here is the translated code part:

我遇到了一个问题可能不是什么大问题基本上我正在使用Google Drive API从Drive检索文件我想要进行分页我成功地做到了下一页但当我尝试实现上一页按钮时出现了问题我设法让它工作但现在如果有2页它就运行正常但如果有超过2页例如如果有3页如果我进入第3页然后点击上一页按钮它会带我到第2页但然后没有previousPageToken”,所以按钮根本不显示我应该将令牌存储在数组中吗

以下是代码

// 在这里插入你的代码

总结一下我只能返回一页然后停在那里因此我可以轻松地转到下一页因为始终有下一页的令牌

谢谢您提前帮助

编辑

所以正如建议的我尝试将页面令牌保存在一个数组中我将它推送到数组中在下一个函数调用时当点击下一页时),令牌从数组中取出我通过`console.log()`检查了令牌是否赋值给`previousPageToken`但由于某种原因在下一页上当我按下上一页按钮时它现在只是刷新同一页这是按钮创建的代码

// 在这里插入你的代码

如果需要进一步的帮助或解释,请随时告诉我。

英文:

I've encountered a problem, probably it's not something huge. So basically I'm using Google Drive API to retrieve files from drive and I want to make pagination, I managed to do next page just fine, but the problem rised when I tried implementing Previous Page button. Imanaged to make it work, but now if there's 2 pages it works just fine, but if there's more than 2, for example, if there are 3 pages, if I go to 3rd page, click Previous Page button, it takes me to 2nd page, but then there's no "previousPageToken" so button is not appearing at all. Should I store tokens in an array or something like that?
Here is the code:


let currentPageToken = null;
let previousPageToken = null;

async function listFiles(folderId, pageToken = null) {
  $('#table_content').empty();
  $('#table_content').remove();
  isListFilesInProgress = true; // Set the flag to indicate listFiles() is in progress

  // Disable the button during listFiles() execution
  $('#show_files_button').prop('disabled', true);

  const request = {
    q: `'${folderId}' in parents`,
    pageSize: 10,
    fields: 'nextPageToken, files(id, name, mimeType, thumbnailLink, webContentLink, modifiedTime)',
    pageToken: pageToken, // Pass the pageToken to retrieve the next page
  };

  gapi.client.drive.files
    .list(request)
    .then(function (response) {
      console.log(response);
      var files = response.result.files;
      if (files && files.length > 0) {
        var table = document.createElement('table');
        table.classList.add('table', 'table-striped');
        table.id = 'table_content';

        var thead = document.createElement('thead');
        var headerRow = document.createElement('tr');
        var header1 = document.createElement('th');
        header1.textContent = 'Thumbnail';
        var header2 = createSortableHeader('Name', 'name');
        var header3 = createSortableHeader('Type', 'mimeType');
        var header4 = createSortableHeader('Last Updated', 'modifiedTime');
        var header5 = document.createElement('th');
        header5.textContent = 'Download';

        headerRow.appendChild(header1);
        headerRow.appendChild(header2);
        headerRow.appendChild(header3);
        headerRow.appendChild(header4);
        headerRow.appendChild(header5);
        thead.appendChild(headerRow);
        table.appendChild(thead);

        var tbody = document.createElement('tbody');
        for (var i = 0; i < files.length; i++) {
          (function (file) {
            var fileName = file.name;
            var mimeType = file.mimeType;
            var thumbnailLink = file.thumbnailLink;
            var downloadLink = file.webContentLink;
            var lastUpdated = new Date(file.modifiedTime).toLocaleString();
            var fileId = file.id;

            var row = document.createElement('tr');

            var thumbnailCell = createThumbnailCell(thumbnailLink, mimeType, fileId);
            row.appendChild(thumbnailCell);

            var nameCell = document.createElement('td');
            nameCell.textContent = fileName;
            row.appendChild(nameCell);

            var typeCell = document.createElement('td');
            typeCell.textContent = mimeType;
            row.appendChild(typeCell);

            var lastUpdatedCell = document.createElement('td');
            lastUpdatedCell.textContent = lastUpdated;
            row.appendChild(lastUpdatedCell);

            if (mimeType != 'application/vnd.google-apps.folder') {
              var downloadCell = document.createElement('td');
              var downloadLinkElem = document.createElement('a');
              downloadLinkElem.href = downloadLink;
              downloadLinkElem.textContent = 'Download';
              downloadLinkElem.classList.add('btn', 'btn-primary');
              downloadLinkElem.target = '_blank';
              downloadCell.appendChild(downloadLinkElem);
              row.appendChild(downloadCell);
            }

            // Add click event listener to navigate into folders
            if (mimeType === 'application/vnd.google-apps.folder') {
              row.classList.add('folder-row');
              row.addEventListener('click', function () {
                var folderId = file.id;
                listFiles(folderId);
              });
            }

            tbody.appendChild(row);
          })(files[i]);
        }

        table.appendChild(tbody);
        document.getElementById('content').appendChild(table);

        // Remove existing Next Page and Previous Page buttons
        $('.next-page-button').remove();
        $('.previous-page-button').remove();

        // Add Next Page button if there is a nextPageToken
        const nextPageToken = response.result.nextPageToken;
        if (nextPageToken) {
          const nextPageButton = document.createElement('button');
          nextPageButton.textContent = 'Next Page';
          nextPageButton.classList.add('btn', 'btn-primary', 'next-page-button');
          nextPageButton.addEventListener('click', function () {
            listFiles(folderId, nextPageToken); // Call listFiles() with the nextPageToken
          });

          document.getElementById('content').appendChild(nextPageButton);
        }

        // Add Previous Page button if there is a pageToken
        if (pageToken) {
          const previousPageButton = document.createElement('button');
          previousPageButton.textContent = 'Previous Page';
          previousPageButton.classList.add('btn', 'btn-primary', 'previous-page-button');
          previousPageButton.addEventListener('click', function () {
            listFiles(folderId); // Call listFiles() without the pageToken to go back to the previous page
          });

          document.getElementById('content').appendChild(previousPageButton);
        }
      }
    })
    .finally(function () {
      isListFilesInProgress = false;
      $('#show_files_button').prop('disabled', false);
    });
}

To sum up, I can only go back one page and it stops there, therefore I can go to next page just fine, because there is always a token for next page.

Thank you in advance!

Edit:

So as suggested I tried keeping page tokens in an array, I push it into an array and on the next function call (when next page is clicked), token is taken from array and I checked with console.log() that token is assigned to previousPageToken, but for some reason on the next page when I press Previous Page button it now just refreshes same page, this is the code of button creation:

const previousPageToken = pageTokens[pageTokens.length - 1];

          console.log('next');
          console.log(nextPageToken);
          console.log('previous');
          console.log(previousPageToken);
          
          if (previousPageToken) {
            const previousPageButton = document.createElement('button');
            previousPageButton.textContent = 'Previous Page';
            previousPageButton.classList.add('btn', 'btn-primary', 'previous-page-button');
            previousPageButton.addEventListener('click', function () {
              listFiles(folderId, previousPageToken); // Call listFiles() with the previousPageToken
            });

            document.getElementById('content').appendChild(previousPageButton);
          }

答案1

得分: 1

测试您试图实现的整体逻辑时,推荐的方法确实是将 nextPageToken 保存在数组中,以便稍后调用。理论上,只需使用 array.push() 就足够了,这也将允许您浏览数组索引,因为您肯定知道新的 'nextPageToken' 将添加到数组的末尾。

我建议参考 Tanaike这个帖子 中的答案,作为令牌管理的参考:

async function main(auth) {
  const drive = google.drive({ version: "v3", auth });

  const fileList = [];
  let NextPageToken = "";
  do {
    const params = {
      // q: "",  // 在这种情况下,这是不必要的。
      orderBy: "name",
      pageToken: NextPageToken || "",
      pageSize: 1000,
      fields: "nextPageToken, files(id, name)",
    };
    const res = await drive.files.list(params);
    Array.prototype.push.apply(fileList, res.data.files);
    NextPageToken = res.data.nextPageToken;
  } while (NextPageToken);

  console.log(fileList.length);  // 您可以在这里看到文件的数量。
}

作为一则附注,请记住 nextPageTokens 的生命周期很短,根据我的经验和其他 Stackoverflow 用户的说法(例如 Linda Lawton - DaImTo ),它们只持续约一个小时

参考:

英文:

Testing the overall logic of what you are trying to achieve, the recommended approach is indeed saving the nextPageToken in an array so it can be called later. In theory, just using an array.push() should suffice, this will also allow you to navigate the array index since you’ll know for sure the new ‘nextPageToken’ will be added at the end of the array.
I can recommend reviewing Tanaike’s answer in this post to use as a reference for the token management:

    async function main(auth) {
const drive = google.drive({ version: "v3", auth });
const fileList = [];
let NextPageToken = "";
do {
const params = {
// q: "",  // In this case, this is not required.
orderBy: "name",
pageToken: NextPageToken || "",
pageSize: 1000,
fields: "nextPageToken, files(id, name)",
};
const res = await drive.files.list(params);
Array.prototype.push.apply(fileList, res.data.files);
NextPageToken = res.data.nextPageToken;
} while (NextPageToken);
console.log(fileList.length);  // You can see the number of files here.
}

As a side note, keep in mind that the nextPageTokens are short-lived, according to my experience and other Stackoverflow users (like Linda Lawton - DaImTo ), they last about an hour

References:

答案2

得分: 1

这是您提供的代码的翻译部分:

所以我终于成功解决了这个问题,所以我将发布一个答案,也许有人会觉得有帮助。首先,我使用数组来存储每一页的当前页面令牌。在单击“上一页”按钮时,我移除数组中的最后一个元素。以下是代码:


// 如果存在 previousPageToken,则添加“上一页”按钮
var previousPageToken = pageTokens[pageTokens.length - 1];
if (pageTokens.length != 0)
{
  if (previousPageToken) {
    const previousPageButton = document.createElement('button');
    previousPageButton.textContent = '上一页';
    previousPageButton.classList.add('btn', 'btn-primary', 'previous-page-button');
    previousPageButton.addEventListener('click', function () {
      pageTokens = pageTokens.slice(0, -1);
      listFiles(folderId, previousPageToken); // 使用 previousPageToken 调用 listFiles()
    });
    document.getElementById('content').appendChild(previousPageButton);
  }
  else if (previousPageToken == null) {
    const previousPageButton = document.createElement('button');
    previousPageButton.textContent = '上一页';
    previousPageButton.classList.add('btn', 'btn-primary', 'previous-page-button');
    previousPageButton.addEventListener('click', function () {
      pageTokens = [];
      listFiles(folderId); // 调用 listFiles(),不带页面令牌
    });
    document.getElementById('content').appendChild(previousPageButton);
  }
}

// 如果存在 nextPageToken,则添加“下一页”按钮
const nextPageToken = response.result.nextPageToken;
if (nextPageToken) {
  const nextPageButton = document.createElement('button');
  nextPageButton.textContent = '下一页';
  nextPageButton.classList.add('btn', 'btn-primary', 'next-page-button');
  nextPageButton.addEventListener('click', function () {
    pageTokens.push(pageToken);
    listFiles(folderId, nextPageToken); // 使用 nextPageToken 调用 listFiles()
  });

  document.getElementById('content').appendChild(nextPageButton);
}

然后我意识到,由于某种原因,我无法获取第一页的页面令牌(它存储为数组中的 null)。因此,我为数组中的最后一个元素为 null 的情况创建了一个单独的“else if”分支,这意味着它是第二页。因此,当我在不带页面令牌的情况下调用我的函数时,默认加载第一页。我还添加了一个检查if (pageTokens.length != 0),以便在第一页时不会呈现“上一页”按钮。

英文:

So I finally managed to solve this problem, so I'll post an answer, maybe someone will find it helpful. First of all, I used array to store current page token, on every page. On "Previous Page" button click, I remove the last element in array. Here's the code:


// Add Previous Page button if there is a previousPageToken
        var previousPageToken = pageTokens[pageTokens.length - 1];
        if (pageTokens.length != 0)
        {
          if (previousPageToken) {
            const previousPageButton = document.createElement('button');
            previousPageButton.textContent = 'Previous Page';
            previousPageButton.classList.add('btn', 'btn-primary', 'previous-page-button');
            previousPageButton.addEventListener('click', function () {
              pageTokens = pageTokens.slice(0, -1);
              listFiles(folderId, previousPageToken); // Call listFiles() with the previousPageToken
            });
            document.getElementById('content').appendChild(previousPageButton);
          }
          else if (previousPageToken == null) {
            const previousPageButton = document.createElement('button');
            previousPageButton.textContent = 'Previous Page';
            previousPageButton.classList.add('btn', 'btn-primary', 'previous-page-button');
            previousPageButton.addEventListener('click', function () {
              pageTokens = [];
              listFiles(folderId); // Call listFiles()
            });
            document.getElementById('content').appendChild(previousPageButton);
          }
        }

        // Add Next Page button if there is a nextPageToken
          const nextPageToken = response.result.nextPageToken;
          if (nextPageToken) {
            const nextPageButton = document.createElement('button');
            nextPageButton.textContent = 'Next Page';
            nextPageButton.classList.add('btn', 'btn-primary', 'next-page-button');
            nextPageButton.addEventListener('click', function () {
              pageTokens.push(pageToken);
              listFiles(folderId, nextPageToken); // Call listFiles() with the nextPageToken
            });

            document.getElementById('content').appendChild(nextPageButton);
          }

Then I've realised, that I can't get first page token for some reason (it was stored as null in array). So I made seperate else if for the case then last element in array is null that meant it was 2nd page. So when I call my function without page token, which on default loads first page. I also made a check if (pageTokens.length != 0) so "Previous Page" button won't render if it is first page.

huangapple
  • 本文由 发表于 2023年5月29日 19:51:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/76357114.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定