ขั้นตอนที่ 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 มีเพียงโปรแกรมรับฟังการคลิกบนปุ่มส่งออกไปยังดิสก์และสตับสําหรับ 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 ที่บันทึกไว้อยู่แล้ว ให้ใช้ 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

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

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

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

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

แอป Todo ที่มีรายการที่ต้องทำซึ่งส่งออกแล้ว

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

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

พร้อมที่จะดำเนินการขั้นตอนถัดไปไหม ไปที่ขั้นตอนที่ 7 - เผยแพร่แอป »