第 6 步:将待办事项导出到文件系统

在此步骤中,您将学习以下内容:

  • 如何获取对外部文件系统中文件的引用。
  • 如何写入文件系统。

完成此步骤预计用时:20 分钟。
若要预览您将在此步骤中完成的内容,请跳转到本页底部 ↓

导出待办事项

此步骤将向应用添加一个导出按钮。点击时,当前的待办事项会保存到文本中 所有文件如果该文件已存在,系统会将其替换。否则,系统会创建一个新文件。

更新权限

对于只读权限,可以采用字符串形式请求文件系统权限,也可以使用 其他属性例如:

// Read only
"permissions": ["fileSystem"]

// Read and write
"permissions": [{"fileSystem": ["write"]}]

// Read, write, autocomplate previous input, and select folder directories instead of files
"permissions": [{"fileSystem": ["write", "retainEntries", "directory"]}]

您需要拥有读写权限。在 manifest.json 中,请求 {fileSystem: [ "write" ] } 权限:

"permissions": [
  "storage", 
  "alarms", 
  "notifications", 
  "webview",
  "<all_urls>", 
  { "fileSystem": ["write"] } 
],

更新 HTML 视图

index.html 中,添加导出到磁盘按钮和 div(应用会显示状态消息):

<footer id="info">
  <button id="toggleAlarm">Activate alarm</button>
  <button id="exportToDisk">Export to disk</button>
  <div id="status"></div>
  ...
</footer>

同样在 index.html 中,加载 export.js 脚本:

...
<script src="js/alarms.js"></script>
<script src="js/export.js"></script>

创建导出脚本

使用以下代码新建一个名为 export.js 的 JavaScript 文件。将其保存在 js 文件夹中。

(function() {

  var dbName = 'todos-vanillajs';

  var savedFileEntry, fileDisplayPath;

  function getTodosAsText(callback) {
  }

  function exportToFileEntry(fileEntry) {
  }

  function doExportToDisk() {
  }

  document.getElementById('exportToDisk').addEventListener('click', doExportToDisk);

})();

目前,export.js 仅包含导出到磁盘按钮上的点击监听器和 getTodosAsText()exportToFileEntrydoExportToDisk()

以文本形式获取待办事项

更新 getTodosAsText(),使其从 chrome.storage.local 读取待办事项并生成文本 表示:

function getTodosAsText(callback) {
  chrome.storage.local.get(dbName, function(storedData) {
    var text = '';

    if ( storedData[dbName].todos ) {
      storedData[dbName].todos.forEach(function(todo) {
          text += '- ';
          if ( todo.completed ) {
            text += '[DONE] ';
          }
          text += todo.title;
          text += '\n';
        }, '');
    }

    callback(text);

  }.bind(this));
}

选择一个文件

使用 chrome.fileSystem.chooseEntry() 更新 doExportToDisk(),以允许用户选择 文件:

function doExportToDisk() {

  if (savedFileEntry) {

    exportToFileEntry(savedFileEntry);

  } else {

    chrome.fileSystem.chooseEntry( {
      type: 'saveFile',
      suggestedName: 'todos.txt',
      accepts: [ { description: 'Text files (*.txt)',
                   extensions: ['txt']} ],
      acceptsAllTypes: true
    }, exportToFileEntry);

  }
}

chrome.fileSystem.chooseEntry() 的第一个参数是选项对象。第二个 参数是一个回调方法。

如果已经保存有 FileEntry,则在调用 exportToFileEntry() 时改用它。文件 引用在表示 FileEntry 的对象生命周期内存在。此示例表示平局 FileEntry 添加到应用窗口,以便 JavaScript 代码无需任何用户即可写入所选文件 互动。

使用 FileEntry 将待办事项写入磁盘

更新 exportToFileEntry() 以通过 FileEntry Web API 将待办事项保存为文本:

function exportToFileEntry(fileEntry) {
  savedFileEntry = fileEntry;

  var status = document.getElementById('status');

  // Use this to get a file path appropriate for displaying
  chrome.fileSystem.getDisplayPath(fileEntry, function(path) {
    fileDisplayPath = path;
    status.innerText = 'Exporting to '+path;
  });

  getTodosAsText( function(contents) {

    fileEntry.createWriter(function(fileWriter) {

      var truncated = false;
      var blob = new Blob([contents]);

      fileWriter.onwriteend = function(e) {
        if (!truncated) {
          truncated = true;
          // You need to explicitly set the file size to truncate
          // any content that might have been there before
          this.truncate(blob.size);
          return;
        }
        status.innerText = 'Export to '+fileDisplayPath+' completed';
      };

      fileWriter.onerror = function(e) {
        status.innerText = 'Export failed: '+e.toString();
      };

      fileWriter.write(blob);

    });
  });
}

chrome.fileSystem.getDisplayPath() 可获取输出到状态的可显示文件路径 div

使用 fileEntry.createWriter() 创建一个 FileWriter 对象。然后,fileWriter.write() 可以写入 Blob 发送到文件系统。使用 fileWriter.onwriteend()fileWriter.onerror() 进行更新 状态为 div

有关 FileEntry 的详细信息,请阅读 HTML5Rocks 上的探索 FileSystem API;或者 请参阅 MDN 上的 FileEntry docs

保留 FileEntry 对象

高级FileEntry 对象无法无限期保留。您的应用需要询问用户 来选择一个文件。如果您的应用因运行时而被强制重启 崩溃或更新,restoreEntry() 是一个恢复 FileEntry 的选项。

如果您愿意,可以尝试保存 retainEntry() 返回的 ID 并在应用中恢复该 ID。 重启。(提示:在后台页面中为 onRestarted 事件添加监听器。)

启动完成的待办事项应用

您已完成第 6 步!重新加载应用并添加一些待办事项。点击导出到磁盘以导出您的 改为.txt 文件

包含导出的待办事项的“待办事项”应用

了解详情

如需详细了解此步骤中引入的一些 API,请参阅:

准备好继续下一步了吗?转到第 7 步 - 发布应用 »