Шаг 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>

Создать скрипт экспорта

Создайте новый файл JavaScript с именем Export.js , используя приведенный ниже код. Сохраните его в папке js .

(function() {

  var dbName = 'todos-vanillajs';

  var savedFileEntry, fileDisplayPath;

  function getTodosAsText(callback) {
  }

  function exportToFileEntry(fileEntry) {
  }

  function doExportToDisk() {
  }

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

})();

На данный момент экспорт.js содержит только прослушиватель кликов на кнопке «Экспорт на диск» и заглушки для getTodosAsText() , exportToFileEntry и doExportToDisk() .

Получить задачи в виде текста

Обновите 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));
}

Выберите файл

Обновите doExportToDisk() с помощью chrome.fileSystem.chooseEntry() , чтобы позволить пользователю выбирать файл:

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() , чтобы сохранять задачи в виде текста через веб-API FileEntry :

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 прочитайте Изучение API-интерфейсов файловой системы на HTML5Rocks или обратитесь к FileEntry docs на MDN.

Сохранение объектов FileEntry

Дополнительно : объекты FileEntry не могут сохраняться бесконечно. Ваше приложение должно просить пользователя выбрать файл каждый раз при запуске приложения. Если ваше приложение было вынуждено перезапуститься из-за сбоя или обновления во время выполнения, restEntry() — это вариант восстановления FileEntry .

Если хотите, поэкспериментируйте, сохранив идентификатор, возвращаемый функцией continueEntry() , и восстановив его при перезапуске приложения. (Подсказка: добавьте прослушиватель к событию onRestarted на фоновой странице.)

Запустите готовое приложение Todo.

Вы закончили Шаг 6! Перезагрузите приложение и добавьте несколько задач. Нажмите «Экспорт на диск» , чтобы экспортировать задачи в файл .txt.

Приложение Todo с экспортированными задачами

Для дополнительной информации

Более подробную информацию о некоторых API, представленных на этом этапе, см.:

Готовы перейти к следующему шагу? Перейдите к шагу 7. Публикация приложения »