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 việc bạn sẽ hoàn thành trong 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 thêm một nút xuất vào ứng dụng. Khi bạn nhấp vào, các mục việc cần làm hiện tại sẽ được lưu thành một văn bản tệp 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 hệ thống tệp dưới dạng một chuỗi cho quyền truy cập chỉ đọc hoặc Đối tượng có quyền truy cập chỉ đọc cá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 {fileSystem: [ "write" ] } quyền:

"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 Export to dis (Xuất sang ổ đĩa) và div để ứng dụng cho thấy 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 vào 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 một trình nghe lượt nhấp trên nút Export to dis (Xuất sang ổ đĩa) và các mã giả lập cho getTodosAsText(), exportToFileEntrydoExportToDisk().

Nhận các 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 văn bản biểu diễ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 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. Thứ hai là một phương thức gọi lại.

Nếu đã có FileEntry đã lưu, hãy sử dụng mã đó khi gọi exportToFileEntry(). Tệp tham chiếu tồn tại trong toàn thời gian của đối tượng biểu thị FileEntry. Ví dụ này liên kết FileEntry vào 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ỳ người dùng 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ị để xuất ra trạng thái div.

Sử dụng fileEntry.createWriter() để tạo đối tượng FileWriter. Sau đó, fileWriter.write() có thể ghi một Blob trong 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 hãy tham khảo FileEntry docs trên MDN.

Lưu trữ các đối tượng FileEntry

Nâng cao: Bạn không thể duy trì đối tượng FileEntry vô thời hạn. Ứng dụng của bạn cần hỏi 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 của bạn buộc phải khởi động lại do thời gian chạy gặp sự cố hoặc cập nhật, restoreEntry() là phương án 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ề rồi khôi phục mã đó trên ứng dụng Khởi động lại. (Gợi ý: Thêm một trình nghe vào sự kiện onRestarted trên trang nền.)

Chạy ứng dụng Việc cần làm đã hoàn thành

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 dis (Xuất sang đĩa) để xuất việc cần làm vào tệp .txt.

Ứng dụng Việc cần làm với 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 chuyển sang bước tiếp theo? Chuyển đến Bước 7 - Xuất bản ứng dụng của bạn »