ขั้นตอนที่ 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 คือเมธอด Callback

หากมี 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 โปรดอ่านการสำรวจ FileSystem API ใน HTML5Rocks หรือ โปรดดู FileEntry docs ใน MDN

ออบเจ็กต์ FileEntry ของ Persist

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

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

เปิดแอป Todo ที่เสร็จสมบูรณ์แล้ว

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

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

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

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

พร้อมก้าวต่อไปหรือยัง ไปที่ขั้นตอนที่ 7 - เผยแพร่แอป »