ขั้นตอนที่ 6: ส่งออกสิ่งที่ต้องทำไปยัง Filesystem

ในขั้นตอนนี้ คุณจะได้เรียนรู้เกี่ยวกับสิ่งต่อไปนี้

  • วิธีรับการอ้างอิงไปยังไฟล์ในระบบไฟล์ภายนอก
  • วิธีเขียนไปยังระบบไฟล์

เวลาโดยประมาณในการทำขั้นตอนนี้ให้เสร็จสิ้นคือ 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);

})();

ขณะนี้ export.js มี Listener การคลิกที่ปุ่มส่งออกไปยังดิสก์เท่านั้น และสตับสำหรับ 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() เป็นออบเจ็กต์ของตัวเลือก พารามิเตอร์ที่ 2 เป็นวิธีเรียกกลับ

หากมี 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 ได้ในการสำรวจ API ของ FileSystem เกี่ยวกับ HTML5Rocks หรือไปที่ FileEntry docs เกี่ยวกับ MDN

คงออบเจ็กต์ FileEntry

ขั้นสูง: FileEntry ออบเจ็กต์ไม่สามารถคงความเดิมได้อย่างไม่มีกำหนด แอปของคุณต้องขอให้ผู้ใช้เลือกไฟล์ทุกครั้งที่เปิดแอป หากระบบบังคับให้แอปรีสตาร์ทเนื่องจากเกิดข้อขัดข้องหรือการอัปเดตรันไทม์ restoreEntry() เป็นตัวเลือกสำหรับกู้คืน FileEntry

หากต้องการ ให้ทดสอบโดยการบันทึกรหัสที่ retainEntry() แสดงผลและกู้คืนเมื่อรีสตาร์ทแอป (คำแนะนำ: เพิ่ม Listener ไปยังเหตุการณ์ onRestarted ในหน้าพื้นหลัง)

เปิดแอป Todo ที่เสร็จแล้ว

คุณทำขั้นตอนที่ 6 เสร็จแล้ว โหลดแอปซ้ำและเพิ่มสิ่งที่ต้องทำ คลิกส่งออกไปยังดิสก์เพื่อส่งออกสิ่งที่ต้องทำเป็นไฟล์ .txt

แอป Todo ที่มีสิ่งที่ต้องทำที่ส่งออก

สำหรับข้อมูลเพิ่มเติม

สำหรับข้อมูลโดยละเอียดเพิ่มเติมเกี่ยวกับ API บางส่วนที่นำมาใช้ในขั้นตอนนี้ โปรดดูที่:

หากพร้อมที่จะไปยังขั้นตอนถัดไปแล้ว ไปที่ขั้นตอนที่ 7 - เผยแพร่แอปของคุณ »