Bước 6: Xuất việc cần làm sang hệ thống tệp

Trong bước này, bạn sẽ tìm hiểu:

  • Cách lấy thông tin tham chiếu đến một tệp trong hệ thống tệp bên ngoài.
  • Cách ghi vào hệ thống tệp.

Thời gian ước tính để hoàn tất bước này: 20 phút.
Để xem trước những nội dung bạn sẽ hoàn tất ở bước này, hãy chuyển xuống cuối trang này ↓.

Xuất việc cần làm

Bước này sẽ thêm một nút xuất vào ứng dụng. Khi được nhấp vào, các mục việc cần làm hiện tại sẽ được lưu vào tệp văn bản do người dùng chọn. Nếu tệp tồn tại, tệp sẽ được thay thế. Nếu không, một tệp mới sẽ được tạo.

Cập nhật quyền

Bạn có thể yêu cầu quyền truy cập hệ thống tệp dưới dạng một chuỗi để truy cập chỉ có thể đọc hoặc dưới dạng một Đối tượng có thuộc tính bổ sung. Ví dụ:

// 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"]}]

Bạn cần có quyền đọc và ghi. Trong tệp manifest.json, hãy yêu cầu cấp quyền {fileSystem: [ "write" ] }:

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

Cập nhật chế độ xem HTML

Trong index.html, hãy thêm nút Xuất sang ổ đĩadiv nơi ứng dụng hiển thị thông báo trạng thái:

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

Ngoài ra, trong index.html, hãy tải tập lệnh export.js:

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

Tạo tập lệnh xuất

Tạo tệp JavaScript mới có tên export.js bằng cách sử dụng mã bên dưới. Lưu tệp này trong thư mục js.

(function() {

  var dbName = 'todos-vanillajs';

  var savedFileEntry, fileDisplayPath;

  function getTodosAsText(callback) {
  }

  function exportToFileEntry(fileEntry) {
  }

  function doExportToDisk() {
  }

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

})();

Hiện tại, export.js chỉ chứa trình nghe lượt nhấp trên nút Export to disk (Xuất sang ổ đĩa) và các mã giả lập cho getTodosAsText(), exportToFileEntrydoExportToDisk().

Nhận mục việc cần làm dưới dạng văn bản

Cập nhật getTodosAsText() để đọc việc cần làm từ chrome.storage.local và tạo nội dung biểu diễn dưới dạng văn bản:

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));
}

Chọn tệp

Cập nhật doExportToDisk() bằng chrome.fileSystem.chooseEntry() để cho phép người dùng chọn một tệp:

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

  }
}

Tham số đầu tiên của chrome.fileSystem.chooseEntry() là một đối tượng của các tuỳ chọn. Tham số thứ hai là phương thức gọi lại.

Nếu đã có một FileEntry đã lưu, hãy sử dụng tệp đó khi gọi exportToFileEntry(). Tham chiếu tệp tồn tại trong toàn thời gian của đối tượng đại diện cho FileEntry. Ví dụ này liên kết FileEntry với cửa sổ ứng dụng để mã JavaScript có thể ghi vào tệp đã chọn mà không cần bất kỳ tương tác nào của người dùng, miễn là cửa sổ ứng dụng vẫn mở.

Sử dụng FileEntry để ghi các mục việc cần làm vào ổ đĩa

Cập nhật exportToFileEntry() để lưu việc cần làm dưới dạng văn bản thông qua API Web 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() nhận một đường dẫn tệp có thể hiển thị, dẫn đến trạng thái div.

Sử dụng fileEntry.createWriter() để tạo đối tượng FileWriter. Sau đó, fileWriter.write() có thể ghi Blob vào hệ thống tệp. Sử dụng fileWriter.onwriteend()fileWriter.onerror() để cập nhật trạng thái div.

Để biết thêm thông tin về FileEntry, hãy đọc bài viết Khám phá các API FileSystem trên HTML5Rocks hoặc tham khảo FileEntry docs trên MDN.

Duy trì các đối tượng FileEntry

Nâng cao: Bạn không thể duy trì các đối tượng FileEntry vô thời hạn. Ứng dụng của bạn cần yêu cầu người dùng chọn một tệp mỗi khi khởi chạy ứng dụng. Nếu ứng dụng bị buộc khởi động lại do sự cố trong thời gian chạy hoặc do cập nhật, thì bạn có thể sử dụng restoreEntry() để khôi phục FileEntry.

Nếu muốn, hãy thử nghiệm bằng cách lưu mã nhận dạng do retainEntry() trả về và khôi phục mã khi khởi động lại ứng dụng. (Gợi ý: Thêm trình nghe vào sự kiện onRestarted trong trang nền.)

Chạy ứng dụng Todo đã hoàn thiện

Bạn đã hoàn tất Bước 6! Tải lại ứng dụng và thêm một số việc cần làm. Nhấp vào Export to disk (Xuất sang ổ đĩa) để xuất việc cần làm của bạn sang tệp .txt.

Ứng dụng Todo với các việc cần làm đã xuất

Thông tin khác

Để biết thêm thông tin chi tiết về một số API được giới thiệu trong bước này, hãy tham khảo:

Bạn đã sẵn sàng để tiếp tục bước tiếp theo? Chuyển tới Bước 7 - Xuất bản ứng dụng của bạn »