การใช้ Google Base และ Google Gears เพื่อประสบการณ์การใช้งานแบบออฟไลน์ที่มีประสิทธิภาพ

บทความแรกในชุด "สร้างแอปพลิเคชัน Ajax ที่ดียิ่งขึ้นด้วย Google APIs"

Dion Almaer และ Pamela Fox, Google
มิถุนายน 2007

หมายเหตุของบรรณาธิการ: Google Gears API ไม่มีให้บริการอีกต่อไป

บทนำ

การรวม Google Base กับ Google Gears จะแสดงให้เห็นวิธีสร้างแอปพลิเคชันที่ใช้แบบออฟไลน์ได้ หลังจากอ่านบทความนี้แล้ว คุณจะคุ้นเคยกับ Google Base API มากขึ้น รวมถึงเข้าใจวิธีใช้ Google Gears ในการจัดเก็บและเข้าถึงค่ากําหนดและข้อมูลของผู้ใช้

ทำความเข้าใจแอป

หากต้องการทำความเข้าใจแอปนี้ คุณควรทำความคุ้นเคยกับ Google Base ก่อน ซึ่งเป็นฐานข้อมูลขนาดใหญ่ของรายการต่างๆ ที่ครอบคลุมหมวดหมู่ต่างๆ เช่น ผลิตภัณฑ์ รีวิว สูตรอาหาร กิจกรรม และอื่นๆ

รายการแต่ละรายการจะมีคำอธิบายประกอบพร้อมชื่อ คำอธิบาย ลิงก์ไปยังแหล่งที่มาของข้อมูล (หากมี) รวมถึงแอตทริบิวต์เพิ่มเติมที่แตกต่างกันไปตามประเภทหมวดหมู่ Google Base ใช้ประโยชน์จากข้อเท็จจริงที่ว่าสินค้าในหมวดหมู่เดียวกันมีชุดแอตทริบิวต์ร่วมกัน เช่น สูตรอาหารทั้งหมดมีส่วนผสม บางครั้งรายการใน Google Base จะปรากฏในผลการค้นหาจาก Google Web Search หรือ Google Product Search ด้วย

แอปเดโม Base with Gears ช่วยให้คุณจัดเก็บและแสดงการค้นหาทั่วไปที่คุณอาจทำใน Google Base เช่น การค้นหาสูตรอาหารที่มี "ช็อกโกแลต" (อร่อย) หรือโฆษณาส่วนตัวที่มี "เดินเล่นริมชายหาด" (โรแมนติก) คุณอาจคิดว่ามันเป็น "Google Base Reader" ที่ให้คุณติดตามการค้นหาและดูผลการค้นหาที่อัปเดตแล้วเมื่อกลับมาที่แอป หรือเมื่อแอปออกไปค้นหาฟีดที่อัปเดตทุกๆ 15 นาที

นักพัฒนาแอปที่ต้องการขยายแอปสามารถเพิ่มฟีเจอร์ต่างๆ เช่น การแจ้งเตือนผู้ใช้ด้วยภาพเมื่อผลการค้นหามีผลการค้นหาใหม่ การให้ผู้ใช้บุ๊กมาร์ก (ติดดาว) รายการโปรด (ออฟไลน์ + ออนไลน์) และการให้ผู้ใช้ค้นหาแอตทริบิวต์เฉพาะหมวดหมู่ เช่น Google Base

การใช้ฟีด Google Base Data API

คุณสามารถค้นหา Google Base โดยใช้โปรแกรมด้วย Google Base Data API ซึ่งเป็นไปตามกรอบ Google Data API โปรโตคอล Google Data API เป็นโปรโตคอลที่เรียบง่ายสำหรับการอ่านและเขียนบนเว็บ และผลิตภัณฑ์ต่างๆ ของ Google จำนวนมากใช้โปรโตคอลนี้ ได้แก่ Picasa, สเปรดชีต, บล็อกเกอร์, ปฏิทิน, Notebook และอื่นๆ

รูปแบบ Google Data API อิงตาม XML และ Atom Publishing Protocol ดังนั้นการโต้ตอบแบบอ่าน/เขียนส่วนใหญ่จึงอยู่ใน XML

ตัวอย่างฟีด Google Base ที่อิงตาม Google Data API มีดังนี้
http://www.google.com/base/feeds/snippets/-/products?bq=digital+camera

snippets ประเภทฟีดจะแสดงฟีดของสินค้าที่เผยแพร่ต่อสาธารณะ -/productsช่วยให้เราจำกัดฟีดไว้เฉพาะหมวดหมู่ผลิตภัณฑ์ได้ และพารามิเตอร์ bq= ช่วยให้เราจำกัดฟีดเพิ่มเติมให้แสดงเฉพาะผลลัพธ์ที่มีคีย์เวิร์ด "กล้องดิจิทัล" หากดูฟีดนี้ในเบราว์เซอร์ คุณจะเห็น XML ที่มีโหนด <entry> พร้อมผลลัพธ์ที่ตรงกัน แต่ละรายการจะมีองค์ประกอบทั่วไปของผู้แต่ง ชื่อ เนื้อหา และลิงก์ แต่ก็จะมีแอตทริบิวต์เพิ่มเติมที่เฉพาะเจาะจงหมวดหมู่ด้วย (เช่น "ราคา" สำหรับรายการในหมวดหมู่ผลิตภัณฑ์)

เนื่องจากข้อจำกัดแบบข้ามโดเมนของ XMLHttpRequest ในเบราว์เซอร์ เราจึงไม่ได้รับอนุญาตให้อ่านฟีด XML จาก www.google.com ในโค้ด JavaScript โดยตรง เราสามารถตั้งค่าพร็อกซีฝั่งเซิร์ฟเวอร์เพื่ออ่าน XML และส่งกลับไปยังตำแหน่งในโดเมนเดียวกันกับแอปของเราได้ แต่เราต้องการหลีกเลี่ยงการเขียนโปรแกรมฝั่งเซิร์ฟเวอร์โดยสิ้นเชิง โชคดีที่ยังมีทางเลือกอื่น

เช่นเดียวกับ Google Data API อื่นๆ Google Base Data API มีตัวเลือกเอาต์พุต JSON นอกเหนือจาก XML มาตรฐาน เอาต์พุตสำหรับฟีดที่เราเห็นก่อนหน้านี้ในรูปแบบ JSON จะอยู่ที่ URL นี้
http://www.google.com/base/feeds/snippets/-/products?bq=digital+camera&alt=json

JSON เป็นรูปแบบการแลกเปลี่ยนที่มีขนาดเล็กซึ่งอนุญาตให้มีการซ้อนกันแบบลำดับชั้นรวมถึงประเภทข้อมูลต่างๆ แต่ที่สำคัญกว่านั้นคือเอาต์พุต JSON เป็นโค้ด JavaScript ดั้งเดิมในตัว จึงโหลดลงในหน้าเว็บได้เพียงแค่การอ้างอิงในแท็กสคริปต์ ซึ่งจะข้ามข้อจำกัดแบบข้ามโดเมน

นอกจากนี้ Google Data APIs ยังให้คุณระบุเอาต์พุต "json-in-script" ด้วยฟังก์ชันเรียกกลับเพื่อดำเนินการเมื่อโหลด JSON แล้ว ซึ่งจะช่วยให้ทำงานกับเอาต์พุต JSON ได้ง่ายยิ่งขึ้น เนื่องจากเราสามารถต่อแท็กสคริปต์แบบไดนามิกลงในหน้าเว็บและระบุฟังก์ชันเรียกกลับที่แตกต่างกันสำหรับแต่ละแท็กได้

ดังนั้น หากต้องการโหลดฟีด JSON ของ Base API ลงในหน้าเว็บแบบไดนามิก เราสามารถใช้ฟังก์ชันต่อไปนี้ซึ่งสร้างแท็กสคริปต์ที่มี URL ของฟีด (ต่อท้ายด้วยค่า altcallback) และต่อท้ายลงในหน้าเว็บ

function getJSON() {
  var script = document.createElement('script');

  var url = "http://www.google.com/base/feeds/snippets/-/products?bq=digital+camera";
  script.setAttribute('src', url + "&alt=json-in-script&callback=listResults");
  script.setAttribute('type', 'text/JavaScript');
  document.documentElement.firstChild.appendChild(script);
}

ตอนนี้ฟังก์ชัน Callback listResults ของเราจึงสามารถวนซ้ำผ่าน JSON ที่ส่งเข้ามาเป็นพารามิเตอร์เดียว และแสดงข้อมูลในแต่ละรายการที่พบในรายการหัวข้อย่อย

  function listTasks(root) {
    var feed = root.feed;
    var html = [''];
    html.push('<ul>');
    for (var i = 0; i < feed.entry.length; ++i) {
      var entry = feed.entry[i];
      var title = entry.title.$t;
      var content = entry.content.$t;
      html.push('<li>', title, ' (', content, ')</li>');
    }
    html.push('</ul>');

    document.getElementById("agenda").innerHTML = html.join("");
  }

การเพิ่ม Google Gears

ตอนนี้เรามีแอปพลิเคชันที่สามารถสื่อสารกับ Google Base ผ่าน Google Data API แล้ว เราจึงต้องการเปิดใช้แอปพลิเคชันนี้ให้ทำงานแบบออฟไลน์ได้ ซึ่ง Google Gears ช่วยคุณได้

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

ในกรณีของเรา เราต้องการให้ผู้ใช้ในเบราว์เซอร์ที่ไม่มี Gears ยังคงใช้แอปได้ ขณะเดียวกันก็มอบสิทธิประโยชน์ในการใช้งานแบบออฟไลน์และ UI ที่ตอบสนองได้ดีขึ้นแก่ผู้ใช้ที่มีปลั๊กอิน

สถาปัตยกรรมของเรามีลักษณะดังนี้

  • เรามีออบเจ็กต์ JavaScript ที่มีหน้าที่จัดเก็บคำค้นหาของคุณและแสดงผลลัพธ์จากคำค้นหาเหล่านี้
  • หากติดตั้ง Google Gears คุณจะได้รับ Gears เวอร์ชันที่จัดเก็บทุกอย่างไว้ในฐานข้อมูลในเครื่อง
  • หากไม่ได้ติดตั้ง Google Gears คุณจะได้รับเวอร์ชันที่จัดเก็บคำค้นหาไว้ในคุกกี้และไม่จัดเก็บผลการค้นหาทั้งหมด (จึงตอบสนองช้าลงเล็กน้อย) เนื่องจากผลการค้นหามีขนาดใหญ่เกินกว่าจะจัดเก็บไว้ในคุกกี้
ข้อดีของสถาปัตยกรรมนี้คือคุณไม่จำเป็นต้องตรวจสอบif (online) {}ทุกที่ แต่แอปพลิเคชันจะมีการตรวจสอบเกียร์ 1 ครั้ง แล้วใช้อะแดปเตอร์ที่ถูกต้อง


การใช้ฐานข้อมูลในเครื่องของ Gears

คอมโพเนนต์หนึ่งของ Gears คือฐานข้อมูล SQLite ในเครื่องที่ฝังไว้และพร้อมให้คุณใช้งาน มี API ฐานข้อมูลที่ใช้งานง่ายซึ่งคุณอาจคุ้นเคยหากเคยใช้ API สำหรับฐานข้อมูลฝั่งเซิร์ฟเวอร์ เช่น MySQL หรือ Oracle

ขั้นตอนการใช้ฐานข้อมูลในเครื่องนั้นง่ายมาก ดังนี้

  • เริ่มต้นออบเจ็กต์ Google Gears
  • รับออบเจ็กต์โรงงานฐานข้อมูลและเปิดฐานข้อมูล
  • เริ่มดำเนินการคำขอ SQL

มาดูขั้นตอนเหล่านี้กันอย่างรวดเร็ว


เริ่มต้นออบเจ็กต์ Google Gears

แอปพลิเคชันควรอ่านเนื้อหาของ /gears/samples/gears_init.js โดยตรงหรือโดยการวางโค้ดลงในไฟล์ JavaScript ของคุณเอง เมื่อ<script src="..../gears_init.js" type="text/JavaScript"></script>แล้ว คุณจะมีสิทธิ์เข้าถึงเนมสเปซ google.gears


รับออบเจ็กต์ Database Factory และเปิดฐานข้อมูล
var db = google.gears.factory.create('beta.database', '1.0');
db.open('testdb');

การเรียกใช้ครั้งเดียวนี้จะให้คุณได้รับออบเจ็กต์ฐานข้อมูลที่ช่วยให้คุณเปิดสคีมาฐานข้อมูลได้ เมื่อคุณเปิดฐานข้อมูล ระบบจะกำหนดขอบเขตผ่านกฎนโยบายต้นทางเดียวกัน ดังนั้น "testdb" ของคุณจึงไม่ขัดแย้งกับ "testdb" ของฉัน


เริ่มดำเนินการคำขอ SQL

ตอนนี้เราพร้อมที่จะส่งคำขอ SQL ไปยังฐานข้อมูลแล้ว เมื่อส่งคำขอ "เลือก" เราจะได้รับชุดผลลัพธ์ที่สามารถวนซ้ำเพื่อดูข้อมูลที่ต้องการได้

var rs = db.execute('select * from foo where name = ?', [ name ]);

คุณสามารถดำเนินการกับชุดผลลัพธ์ที่ส่งคืนได้ด้วยวิธีต่อไปนี้

booleanisValidRow()
voidnext()
voidclose()
intfieldCount()
stringfieldName(int fieldIndex)
variantfield(int fieldIndex)
variantfieldByName(string fieldname)

โปรดดูรายละเอียดเพิ่มเติมในเอกสารประกอบเกี่ยวกับ Database Module API (หมายเหตุของบรรณาธิการ: Google Gears API ไม่มีให้บริการอีกต่อไป)


การใช้ GearsDB เพื่อห่อหุ้ม API ระดับต่ำ

เราต้องการสรุปและทำให้งานฐานข้อมูลทั่วไปบางอย่างสะดวกยิ่งขึ้น ตัวอย่างเช่น

  • เราต้องการมีวิธีที่ดีในการบันทึก SQL ที่สร้างขึ้นเมื่อเราแก้ไขข้อบกพร่องของแอปพลิเคชัน
  • เราต้องการจัดการข้อยกเว้นในที่เดียวแทนที่จะต้องtry{}catch(){}ทุกที่
  • เราต้องการจัดการกับออบเจ็กต์ JavaScript แทนชุดผลลัพธ์เมื่ออ่านหรือเขียนข้อมูล

เราจึงสร้าง GearsDB ซึ่งเป็นไลบรารีโอเพนซอร์สที่ครอบคลุมออบเจ็กต์ฐานข้อมูล เพื่อจัดการปัญหาเหล่านี้ในลักษณะทั่วไป ตอนนี้เราจะแสดงวิธีใช้ GearsDB

การตั้งค่าเบื้องต้น

ในโค้ด window.onload เราต้องตรวจสอบว่าตารางฐานข้อมูลที่เราใช้มีอยู่ หากผู้ใช้ติดตั้ง Gears ไว้เมื่อโค้ดต่อไปนี้ทํางาน ระบบจะสร้างออบเจ็กต์ GearsBaseContent

content = hasGears() ? new GearsBaseContent() : new CookieBaseContent();

จากนั้นเราจะเปิดฐานข้อมูลและสร้างตารางหากยังไม่มี

db = new GearsDB('gears-base'); // db is defined as a global for reuse later!

if (db) {
  db.run('create table if not exists BaseQueries' +
         ' (Phrase varchar(255), Itemtype varchar(100))');
  db.run('create table if not exists BaseFeeds' + 
         ' (id varchar(255), JSON text)');
}

ตอนนี้เรามั่นใจว่าเรามีตารางที่จะจัดเก็บคำค้นหาและฟีด โค้ด new GearsDB(name) จะห่อหุ้มการเปิดฐานข้อมูลด้วยชื่อที่ระบุ เมธอด run จะรวมเมธอด execute ระดับล่างไว้ด้วย แต่ยังจัดการเอาต์พุตการแก้ไขข้อบกพร่องไปยังคอนโซลและดักจับข้อยกเว้นด้วย


การเพิ่มข้อความค้นหา

เมื่อเรียกใช้แอปเป็นครั้งแรก คุณจะยังไม่มีการค้นหา หากคุณพยายามค้นหา Nintendo Wii ในผลิตภัณฑ์ เราจะบันทึกคำค้นหานี้ในตาราง BaseQueries

addQuery เวอร์ชัน Gears จะทำเช่นนี้โดยรับอินพุตและบันทึกผ่าน insertRow ดังนี้

var searchterm = { Phrase: phrase, Itemtype: itemtype };
db.insertRow('BaseQueries', searchterm); 

insertRow จะใช้ออบเจ็กต์ JavaScript (searchterm) และจัดการการแทรกลงในตารางให้คุณ นอกจากนี้ยังช่วยให้คุณกำหนดข้อจำกัดได้ด้วย (เช่น การแทรกบล็อกที่ไม่ซ้ำกันของ "บ็อบ" มากกว่า 1 รายการ) อย่างไรก็ตาม โดยส่วนใหญ่แล้วคุณจะต้องจัดการข้อจำกัดเหล่านี้ในฐานข้อมูลเอง


การรับข้อความค้นหาทั้งหมด

เราใช้ตัวเลือกแบบดรอปดาวน์ที่สวยงามชื่อ selectAll เพื่อแสดงรายการการค้นหาที่ผ่านมา

GearsBaseContent.prototype.getQueries = function() {
  return this.db.selectAll('select * from BaseQueries');
}

ซึ่งจะแสดงผลอาร์เรย์ของออบเจ็กต์ JavaScript ที่ตรงกับแถวในฐานข้อมูล (เช่น [ { Phrase: 'Nintendo Wii', Itemtype: 'product' }, { ... }, ...])

ในกรณีนี้ คุณสามารถแสดงรายการทั้งหมดได้ แต่หากมีข้อมูลจำนวนมาก คุณอาจต้องใช้การเรียกกลับในการเรียกใช้ SELECT เพื่อให้ดำเนินการกับแต่ละแถวที่ส่งคืนได้เมื่อได้รับ

 db.selectAll('select * from BaseQueries where Itemtype = ?', ['product'], function(row) {
  ... do something with this row ...
});

วิธีการเลือกอื่นๆ ที่มีประโยชน์ใน GearsDB มีดังนี้

selectOne(sql, args)แสดงออบเจ็กต์ JavaScript ที่ตรงกันรายการแรก/รายการเดียว
selectRow(table, where, args, select)โดยปกติจะใช้ในกรณีที่ง่ายๆ เพื่อไม่สนใจ SQL
selectRows(table, where, args, callback, select)เหมือนกับ selectRow แต่ใช้กับผลลัพธ์หลายรายการ

การโหลดฟีด

เมื่อได้รับฟีดผลลัพธ์จาก Google Base เราต้องบันทึกลงในฐานข้อมูล

content.setFeed({ id: id, JSON: json.toJSONString() });

... which calls ...

GearsBaseContent.prototype.setFeed = function(feed) {
  this.db.forceRow('BaseFeeds', feed);
}

ก่อนอื่นเราจะใช้ฟีด JSON และแสดงผลเป็นสตริงโดยใช้วิธี toJSONString จากนั้นเราจะสร้างออบเจ็กต์ feed และส่งไปยังเมธอด forceRow forceRow จะแทรกรายการหากยังไม่มี หรืออัปเดตรายการที่มีอยู่


การแสดงผลการค้นหา

แอปของเราจะแสดงผลการค้นหาที่ระบุในแผงด้านขวาของหน้า วิธีที่เราดึงข้อมูลฟีดที่เชื่อมโยงกับข้อความค้นหามีดังนี้

GearsBaseContent.prototype.getFeed = function(url) {
  var row = this.db.selectRow('BaseFeeds', 'id = ?', [ url ]);
  return row.JSON;
}

ตอนนี้เรามี JSON สำหรับแถวแล้ว เราสามารถeval()เพื่อรับออบเจ็กต์กลับมาได้

eval("var json = " + jsonString + ";");

เราพร้อมแล้วที่จะเริ่มใช้ innerHTML เพื่อใส่เนื้อหาจาก JSON ลงในหน้าเว็บ


การใช้ที่เก็บทรัพยากรสำหรับการเข้าถึงแบบออฟไลน์

เนื่องจากเราดึงเนื้อหาจากฐานข้อมูลในเครื่อง แอปนี้จึงควรทำงานแบบออฟไลน์ได้ด้วยใช่ไหม

ไม่เลย ปัญหาคือการเริ่มต้นแอปนี้ คุณต้องโหลดทรัพยากรเว็บของแอป เช่น JavaScript, CSS, HTML และรูปภาพ ปัจจุบันหากผู้ใช้ทำตามขั้นตอนต่อไปนี้ แอปอาจยังคงทำงานได้ นั่นคือ เริ่มออนไลน์ ทำการค้นหาบางอย่าง อย่าปิดเบราว์เซอร์ และเปลี่ยนเป็นออฟไลน์ วิธีนี้อาจใช้ได้เนื่องจากรายการจะยังอยู่ในแคชของเบราว์เซอร์ แต่จะเกิดอะไรขึ้นหากไม่ใช่กรณีนี้ เราต้องการให้ผู้ใช้เข้าถึงแอปได้ตั้งแต่ต้น หลังจากการรีบูต ฯลฯ

โดยเราใช้คอมโพเนนต์ LocalServer และบันทึกทรัพยากรของเรา เมื่อคุณแคปเจอร์ทรัพยากร (เช่น HTML และ JavaScript ที่จำเป็นต่อการเรียกใช้แอปพลิเคชัน) Gears จะบันทึกรายการเหล่านี้ไว้และจะดักคำขอจากเบราว์เซอร์เพื่อส่งคืนรายการเหล่านั้นด้วย เซิร์ฟเวอร์ภายในจะทำหน้าที่เป็นตำรวจจราจรและส่งคืนเนื้อหาที่บันทึกไว้จากร้านค้า

นอกจากนี้ เรายังใช้คอมโพเนนต์ ResourceStore ซึ่งกำหนดให้คุณต้องบอกระบบด้วยตนเองว่าต้องการบันทึกไฟล์ใด ในหลายๆ สถานการณ์ คุณอาจต้องการกำหนดเวอร์ชันของแอปพลิเคชันและอนุญาตให้อัปเกรดในลักษณะธุรกรรม ชุดทรัพยากรจะกำหนดเวอร์ชันร่วมกัน และเมื่อเผยแพร่ชุดทรัพยากรใหม่ คุณอาจต้องการให้ผู้ใช้อัปเกรดไฟล์ได้อย่างราบรื่น หากใช้โมเดลดังกล่าว คุณจะต้องใช้ ManagedResourceStore API

ออบเจ็กต์ GearsBaseContent จะทำสิ่งต่อไปนี้เพื่อบันทึกทรัพยากร

  1. ตั้งค่าอาร์เรย์ของไฟล์ที่ต้องบันทึก
  2. สร้าง LocalServer
  3. เปิดหรือสร้าง ResourceStore ใหม่
  4. โทรออกเพื่อบันทึกหน้าเว็บลงใน Store
// Step 1
this.storeName = 'gears-base';
this.pageFiles = [
  location.pathname,
  'gears_base.js',
  '../scripts/gears_db.js',
  '../scripts/firebug/firebug.js',
  '../scripts/firebug/firebug.html',
  '../scripts/firebug/firebug.css',
  '../scripts/json_util.js',    'style.css',
  'capture.gif' ];

// Step 2
try {
  this.localServer = google.gears.factory.create('beta.localserver', '1.0');
} catch (e) {
  alert('Could not create local server: ' + e.message);
  return;
}

// Step 3
this.store = this.localServer.openStore(this.storeName) || this.localServer.createStore(this.storeName);

// Step 4
this.capturePageFiles();

... which calls ...

GearsBaseContent.prototype.capturePageFiles = function() {
  this.store.capture(this.pageFiles, function(url, success, captureId) {
    console.log(url + ' capture ' + (success ? 'succeeded' : 'failed'));
  });
}

สิ่งสำคัญที่ควรทราบในที่นี้คือคุณจะบันทึกทรัพยากรได้เฉพาะในโดเมนของคุณเองเท่านั้น เราพบข้อจำกัดนี้เมื่อพยายามเข้าถึงไฟล์ JavaScript ของ GearsDB โดยตรงจากไฟล์ "gears_db.js" ต้นฉบับใน SVN Trunk แน่นอนว่าโซลูชันนั้นง่ายมาก คุณเพียงแค่ต้องดาวน์โหลดทรัพยากรภายนอกและวางไว้ภายใต้โดเมนของคุณ โปรดทราบว่าการเปลี่ยนเส้นทาง 302 หรือ 301 จะไม่ทำงาน เนื่องจาก LocalServer ยอมรับเฉพาะรหัสเซิร์ฟเวอร์ 200 (สำเร็จ) หรือ 304 (ไม่มีการแก้ไข) เท่านั้น

ซึ่งมีผลกระทบดังนี้ หากวางรูปภาพไว้ที่ images.yourdomain.com คุณจะจับภาพไม่ได้ เนื่องจาก www1 และ www2 มองไม่เห็นกัน คุณตั้งค่าพร็อกซีฝั่งเซิร์ฟเวอร์ได้ แต่การดำเนินการดังกล่าวจะขัดต่อวัตถุประสงค์ของการแยกแอปพลิเคชันไปยังหลายโดเมน

การแก้ไขข้อบกพร่องของแอปพลิเคชันออฟไลน์

การแก้ไขข้อบกพร่องของแอปพลิเคชันที่ทำงานแบบออฟไลน์จะมีความซับซ้อนมากขึ้นเล็กน้อย ตอนนี้มีสถานการณ์ให้ทดสอบมากขึ้นแล้ว ดังนี้

  • ฉันออนไลน์และแอปทำงานในแคชอย่างเต็มรูปแบบ
  • ฉันออนไลน์อยู่แต่ไม่ได้เข้าถึงแอป และไม่มีอะไรในแคช
  • ฉันออฟไลน์อยู่แต่เข้าถึงแอปได้
  • ฉันออฟไลน์และไม่เคยเข้าถึงแอป (ไม่ควรเป็นแบบนี้!)

เราใช้รูปแบบต่อไปนี้เพื่อให้การทำงานง่ายขึ้น

  • เราจะปิดใช้แคชใน Firefox (หรือเบราว์เซอร์ที่คุณเลือก) เมื่อต้องการตรวจสอบว่าเบราว์เซอร์ไม่ได้เลือกบางอย่างจากแคช
  • เราแก้ไขข้อบกพร่องโดยใช้ Firebug (และ Firebug Lite สำหรับการทดสอบในเบราว์เซอร์อื่นๆ) เราใช้ console.log() ในทุกที่ และตรวจหาคอนโซลในกรณีที่จำเป็น
  • เราเพิ่มโค้ด JavaScript ตัวช่วยในส่วนต่อไปนี้
    • ช่วยให้เราล้างฐานข้อมูลและเริ่มต้นใหม่ได้
    • นำไฟล์ที่บันทึกไว้ออก เพื่อให้เมื่อคุณโหลดซ้ำ ระบบจะไปที่อินเทอร์เน็ตเพื่อรับไฟล์เหล่านั้นอีกครั้ง (มีประโยชน์เมื่อคุณทำการพัฒนาซ้ำๆ ;)

วิดเจ็ตการแก้ไขข้อบกพร่องจะปรากฏทางด้านซ้ายของหน้าก็ต่อเมื่อคุณติดตั้ง Gears โดยมีข้อความที่ไฮไลต์โค้ดที่ต้องล้างข้อมูลดังนี้

GearsBaseContent.prototype.clearServer = function() {
  if (this.localServer.openStore(this.storeName)) {
    this.localServer.removeStore(this.storeName);
    this.store = null;
  }
}

GearsBaseContent.prototype.clearTables = function() {
  if (this.db) {
    this.db.run('delete from BaseQueries');
    this.db.run('delete from BaseFeeds');
  }
  displayQueries();
}

บทสรุป

คุณจะเห็นว่าการทำงานกับ Google Gears นั้นค่อนข้างง่าย เราใช้ GearsDB เพื่อให้คอมโพเนนต์ฐานข้อมูลง่ายยิ่งขึ้น และใช้ ResourceStore แบบแมนนวล ซึ่งใช้งานได้ดีกับตัวอย่างของเรา

ส่วนที่คุณใช้เวลามากที่สุดคือการกำหนดกลยุทธ์สำหรับเวลาที่จะนำข้อมูลออนไลน์และวิธีจัดเก็บข้อมูลแบบออฟไลน์ คุณควรใช้เวลาในการกำหนดสคีมาฐานข้อมูล หากคุณต้องการเปลี่ยนสคีมาในอนาคต คุณจะต้องจัดการการเปลี่ยนแปลงนั้นเนื่องจากผู้ใช้ปัจจุบันจะมีฐานข้อมูลเวอร์ชันหนึ่งอยู่แล้ว ซึ่งหมายความว่าคุณจะต้องจัดส่งโค้ดสคริปต์พร้อมกับการอัปเกรด db แน่นอนว่าการลดการเปลี่ยนแปลงนี้จะช่วยได้ และคุณอาจลองใช้ GearShift ซึ่งเป็นไลบรารีขนาดเล็กที่อาจช่วยคุณจัดการการแก้ไขได้

นอกจากนี้ เรายังใช้ ManagedResourceStore เพื่อติดตามไฟล์ได้ด้วย ซึ่งจะส่งผลดังนี้

  • เราจะปฏิบัติตามกฎระเบียบและจัดเวอร์ชันไฟล์เพื่อให้การอัปเกรดในอนาคตเป็นไปอย่างราบรื่น
  • ManagedResourceStore มีฟีเจอร์ที่ช่วยให้คุณตั้งค่าแทน URL เป็นเนื้อหาอื่นได้ ตัวเลือกสถาปัตยกรรมที่ถูกต้องคือการทำให้ gears_base.js เป็นเวอร์ชันที่ไม่ใช่ Gears และตั้งค่าแทนเพื่อให้ Gears เองดาวน์โหลด gears_base_withgears.js ซึ่งจะมีฟีเจอร์รองรับการทำงานแบบออฟไลน์ทั้งหมด
สำหรับแอปของเรา เราคิดว่าการมีอินเทอร์เฟซเดียวและใช้ใน 2 วิธีจะง่ายกว่า

เราหวังว่าคุณจะสนุกและสมัครเข้าร่วมโปรแกรม Gearing up ได้อย่างง่ายดาย หากมีคำถามหรือมีแอปที่ต้องการแชร์ โปรดเข้าร่วมฟอรัม Google Gears