Langkah 5: Tambahkan Gambar dari Web

Pada langkah ini, Anda akan mempelajari:

  • Cara memuat resource dari luar aplikasi dan menambahkannya ke DOM melalui XHR dan ObjectURLs.

Perkiraan waktu untuk menyelesaikan langkah ini: 20 menit.
Untuk melihat pratinjau tugas yang akan Anda selesaikan di langkah ini, langsung ke bagian bawah halaman ini ↓.

Cara CSP memengaruhi penggunaan resource eksternal

Platform Aplikasi Chrome memaksa aplikasi Anda untuk sepenuhnya mematuhi Kebijakan Keamanan Konten (CSP). Anda tidak dapat langsung memuat resource DOM seperti gambar, font, dan CSS dari luar paket Aplikasi Chrome.

Jika ingin menampilkan gambar eksternal di aplikasi, Anda harus memintanya melalui XMLHttpRequest, mengubahnya menjadi Blob, dan membuat ObjectURL. ObjectURL ini dapat ditambahkan ke DOM karena merujuk pada item dalam memori dalam konteks aplikasi.

Tampilkan gambar thumbnail untuk item daftar tugas

Mari kita ubah aplikasi untuk mencari URL gambar dalam item daftar tugas. Jika URL terlihat seperti gambar (misalnya, diakhiri dengan .png, .jpg, .svg, atau .gif), terapkan proses yang disebutkan di atas untuk menampilkan thumbnail gambar di samping URL.

Update izin

Di Aplikasi Chrome, Anda dapat melakukan panggilan XMLHttpRequest ke URL apa pun selama Anda menentukan domainnya dalam manifes. Karena Anda tidak tahu sebelumnya URL gambar apa yang akan diketik pengguna, mintalah izin untuk membuat permintaan ke "<all_urls>".

Di manifest.json, minta izin "":

"permissions": ["storage", "alarms", "notifications",
                "webview", "<all_urls>"],

Membuat dan menghapus ObjectURL

Di controller.js, tambahkan metode _createObjectURL() untuk membuat ObjectURL dari Blob:

Controller.prototype._createObjectURL = function(blob) {
  var objURL = URL.createObjectURL(blob);
  this.objectURLs = this.objectURLs || [];
  this.objectURLs.push(objURL);
  return objURL;
};

ObjectURLs menyimpan memori, jadi bila Anda tidak lagi memerlukan ObjectURL, Anda harus mencabutnya. Tambahkan metode _clearObjectURL() ini ke controller.js untuk menanganinya:

Controller.prototype._clearObjectURL = function() {
  if (this.objectURLs) {
    this.objectURLs.forEach(function(objURL) {
      URL.revokeObjectURL(objURL);
    });
    this.objectURLs = null;
  }
};

Membuat permintaan XHR

Tambahkan metode _requestRemoteImageAndAppend() untuk menjalankan XMLHttpRequest pada URL gambar tertentu:

Controller.prototype._requestRemoteImageAndAppend = function(imageUrl, element) {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', imageUrl);
  xhr.responseType = 'blob';
  xhr.onload = function() {
    var img = document.createElement('img');
    img.setAttribute('data-src', imageUrl);
    img.className = 'icon';
    var objURL = this._createObjectURL(xhr.response);
    img.setAttribute('src', objURL);
    element.appendChild(img);
  }.bind(this);
  xhr.send();
};

Pada pemuatan XHR, metode ini membuat ObjectURL dari respons XHR, dan menambahkan elemen <img> dengan ObjectURL ini ke DOM.

Mengurai URL gambar dalam item daftar tugas

Sekarang tambahkan metode _parseForImageURLs() yang menemukan semua link yang belum diproses dan memeriksa apakah ada gambar. Untuk setiap URL yang terlihat seperti gambar, jalankan _requestRemoteImageAndAppend():

Controller.prototype._parseForImageURLs = function () {
  // remove old blobs to avoid memory leak:
  this._clearObjectURL();
  var links = this.$todoList.querySelectorAll('a[data-src]:not(.thumbnail)');
  var re = /\.(png|jpg|jpeg|svg|gif)$/;
  for (var i = 0; i<links.length; i++) {
    var url = links[i].getAttribute('data-src');
    if (re.test(url)) {
      links[i].classList.add('thumbnail');
      this._requestRemoteImageAndAppend(url, links[i]);
    }
  }
};

Merender thumbnail dalam daftar tugas

Sekarang panggil _parseForImageURLs() dari showAll(), showActive(), dan showCompleted():

/**
 * An event to fire on load. Will get all items and display them in the
 * todo-list
 */
Controller.prototype.showAll = function () {
  this.model.read(function (data) {
    this.$todoList.innerHTML = this._parseForURLs(this.view.show(data));
    this._parseForImageURLs();
  }.bind(this));
};

/**
 * Renders all active tasks
 */
Controller.prototype.showActive = function () {
  this.model.read({ completed: 0 }, function (data) {
    this.$todoList.innerHTML = this._parseForURLs(this.view.show(data));
    this._parseForImageURLs();
  }.bind(this));
};

/**
 * Renders all completed tasks
 */
Controller.prototype.showCompleted = function () {
  this.model.read({ completed: 1 }, function (data) {
    this.$todoList.innerHTML = this._parseForURLs(this.view.show(data));
    this._parseForImageURLs();
  }.bind(this));
};

Lakukan hal yang sama untuk editItem():

Controller.prototype.editItem = function (id, label) {
  ...
  var onSaveHandler = function () {
    ...
    if (value.length && !discarding) {
      ...
      label.innerHTML = this._parseForURLs(value);
      this._parseForImageURLs();
    } else if (value.length === 0) {
  ...
}

Membatasi dimensi gambar yang ditampilkan

Terakhir, di _bowercomponents/todomvc-common/base.css, tambahkan aturan CSS untuk membatasi ukuran gambar:

.thumbnail img[data-src] {
  max-width: 100px;
  max-height: 28px;
}

Luncurkan aplikasi Daftar tugas yang telah selesai

Anda menyelesaikan Langkah 5! Muat ulang aplikasi Anda dan tambahkan item daftar tugas dengan URL ke gambar yang dihosting secara online. Beberapa URL yang dapat Anda gunakan: http://goo.gl/nqHMF#.jpg atau http://goo.gl/HPBGR#.png.

Untuk informasi selengkapnya

Untuk informasi lebih detail tentang beberapa API yang diperkenalkan di langkah ini, lihat:

Siap untuk melanjutkan ke langkah berikutnya? Lihat Langkah 6 - Ekspor daftar tugas ke sistem file »