Ractive.js - Aplikasi Web Menjadi Mudah

Diterbitkan: 2022-03-11

Dalam lanskap kerangka kerja dan pustaka JavaScript yang berkembang pesat saat ini, memilih salah satu di mana Anda ingin mendasarkan pengembangan Anda bisa menjadi tantangan yang cukup besar. Lagi pula, begitu Anda menggunakan kerangka kerja tertentu, memigrasikan kode Anda untuk menggunakan yang berbeda adalah tugas non-sepele yang mungkin tidak pernah Anda miliki waktu atau anggaran untuk melakukannya.

Jadi, mengapa Ractive.js?

Tidak seperti alat lain yang menghasilkan HTML inert, Ractive mengubah template menjadi cetak biru untuk aplikasi yang interaktif secara default. Dan sementara orang pasti bisa berargumen bahwa kontribusi Ractive lebih evolusioner daripada revolusioner, nilainya tetap signifikan.

Apa yang membuat Ractive sangat berguna adalah ia menyediakan kemampuan yang kuat, tetapi melakukannya dengan cara yang sangat sederhana untuk digunakan oleh pengembang. Selain itu, ini cukup elegan, cepat, tidak mencolok, dan kecil.

Dalam artikel ini, kita akan membahas proses pembuatan aplikasi pencarian Ractive sederhana, mendemonstrasikan beberapa fitur utama Ractive dan cara membantu menyederhanakan aplikasi dan pengembangan web.

Ractive.js dan aplikasi web

Apa itu Ractive.js?

Ractive awalnya dibuat untuk mengatasi masalah pengikatan data dengan cara yang lebih elegan. Untuk itu, dibutuhkan template dan mengubahnya menjadi representasi virtual DOM yang ringan sehingga, ketika data berubah, DOM yang sebenarnya diperbarui secara cerdas dan efisien.

Tetapi segera menjadi jelas bahwa pendekatan dan infrastruktur yang digunakan oleh Ractive dapat digunakan untuk melakukan hal-hal lain dengan lebih efisien juga. Ini dapat, misalnya, secara otomatis menangani hal-hal seperti menggunakan kembali event handler dan secara otomatis melepaskan ikatannya saat tidak lagi diperlukan. Delegasi acara menjadi tidak perlu. Seperti halnya pengikatan data, pendekatan ini mencegah kode menjadi berat saat aplikasi berkembang.

Fitur utama seperti pengikatan dua arah, animasi, dan dukungan SVG disediakan langsung, dan fungsionalitas khusus dapat dengan mudah ditambahkan melalui plugin.

Sementara beberapa alat dan kerangka kerja memaksa Anda untuk mempelajari kosakata baru dan menyusun aplikasi Anda dengan cara tertentu, Ractive bekerja untuk Anda, bukan sebaliknya. Ini juga terintegrasi dengan baik dengan perpustakaan lain.

Aplikasi Sampel kami

Aplikasi sampel kami akan digunakan untuk mencari basis data pengembang Toptal berdasarkan keterampilan. Aplikasi kami akan memiliki dua tampilan:

  • Cari: daftar keterampilan dengan kotak pencarian sebaris
  • Hasil: tampilan keterampilan termasuk daftar pengembang

Untuk setiap pengembang, kami akan menampilkan nama, foto, deskripsi singkat, dan daftar keterampilan mereka (setiap keterampilan akan ditautkan ke tampilan keterampilan yang sesuai).

(Catatan: Tautan ke instance aplikasi yang berfungsi online dan repositori kode sumber disediakan di akhir artikel ini.)

Untuk mempertahankan fokus utama kami pada kerangka kerja Ractive, kami akan menerapkan sejumlah penyederhanaan yang biasanya tidak boleh dilakukan dalam produksi:

  • Tema bawaan. Kami akan menggunakan Bootstrap dengan tema default untuk penataan, daripada menyesuaikan tema agar sesuai dengan gaya aplikasi Anda.
  • Ketergantungan. Kami akan menambahkan dependensi kami sebagai skrip terpisah yang mendefinisikan variabel global (daripada menggunakan modul ES6, atau CommonJS, atau AMD dengan pemuat yang tepat untuk pengembangan, dan langkah pembuatan untuk produksi).
  • Data statis. Kami akan menggunakan data statis yang saya siapkan dengan menggores halaman publik di situs Toptal.
  • Tidak ada perutean sisi klien. Ini berarti bahwa URL akan tetap sama saat kita beralih antar tampilan. Anda pasti tidak boleh melakukannya untuk SPA, meskipun mungkin OK untuk beberapa komponen interaktif kecil. Ractive tidak memiliki implementasi router bawaan, tetapi dapat digunakan dengan router pihak ketiga, seperti yang ditunjukkan dalam contoh ini.
  • Templat yang ditentukan di dalam tag skrip dalam HTML. Ini tidak selalu merupakan ide yang buruk, terutama untuk aplikasi kecil, dan memiliki beberapa keuntungan (sederhana, dan Anda dapat memproses template sisi klien ini bersama dengan template sisi server Anda, misalnya untuk internasionalisasi). Tetapi untuk aplikasi yang lebih besar, Anda dapat memanfaatkan pra-kompilasi (alias, templat pra-parsing ke representasi JS internal.

Mari Memulai dengan Aplikasi Web

Oke, jadi dengan itu, mari kita mulai membangun aplikasi. Kami akan melakukannya secara berulang, menambahkan fitur yang lebih kecil satu per satu dan menjelajahi konsep saat kami menemukannya.

Mari kita mulai dengan membuat folder dengan dua file di dalamnya: index.html dan script.js . Aplikasi kami akan sangat sederhana dan akan bekerja dari file:// protokol untuk menghindari kebutuhan untuk memulai server pengembangan (walaupun Anda bisa jika Anda mau).

Halaman Pencarian

Kami akan mulai dengan menerapkan halaman pencarian di mana pengguna dapat memilih keterampilan untuk menemukan pengembang yang cocok di database Toptal.

Kerangka HTML

Mari kita mulai dengan halaman HTML sepele ini:

 <html> <head> <title>Toptal Search</title> <!-- LOAD BOOTSTRAP FROM THE CDN --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"> </head> <body> <!-- SOME BASIC STATIC CONTENT --> <div class="container"> <h1>Toptal Search</h1> </div> <!-- LOAD THE JAVASCRIPT LIBRARIES WE NEED --> <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.9.3/lodash.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/ractive/0.7.3/ractive.min.js"></script> <!-- LOAD THE DATA --> <script src="https://rawgit.com/emirotin/toptal-blog-ractive/master/data.js"></script> <!-- LOAD OUR SCRIPT --> <script src="script.js"></script> </body> </html>

Seperti yang Anda lihat, ini adalah dokumen HTML5 yang sepele. Ini memuat Bootstrap dari CDN, Lodash (perpustakaan manipulasi data yang mengagumkan), dan Ractive.js.

Ractive tidak perlu mencurahkan seluruh halaman ke SPA, jadi kami dapat memiliki beberapa konten statis. Dalam kasus kami, ini terdiri dari elemen wadah dan judul halaman.

Terakhir, kami memuat data yang telah saya siapkan untuk demo, dan skrip yang akan berisi program kami.

Oke, sekarang kerangka HTML kita sudah siap, mari kita mulai menambahkan beberapa fungsionalitas nyata.

Daftar Keterampilan

Salah satu hal yang saya sangat suka tentang Ractive adalah bagaimana ia mengajarkan Anda untuk berpikir tentang representasi akhir (HTML) yang ingin Anda capai, dan kemudian memungkinkan Anda untuk fokus pada penulisan bit kode yang diperlukan untuk mewujudkannya.

Jadi pertama, mari kita buat daftar keterampilan sebagai tampilan awal kita. Melakukan ini hanya memerlukan:

  • Menambahkan elemen HTML di mana daftar keterampilan akan ditampilkan.
  • Menambahkan potongan kecil kode template ke HTML kita.
  • Menulis beberapa JavaScript singkat dan sederhana yang memasok data ke template, untuk merendernya dalam elemen HTML yang kita tambahkan.

Mod untuk HTML terdiri dari berikut ini:

 <div class="container"> <h1>Toptal Search</h1> <div></div> <!-- THIS IS THE NEW HTML ELEMENT --> </div> <!-- THIS IS THE SMALL SNIPPET OF TEMPLATE CODE --> <script type="text/html"> <div class="row"> {{#each skills}} <span class="col-xs-3"> <a href="#" class="label label-primary">{{this}}</a> </span> {{/each}} </div> </script>

Tidak ada konvensi khusus dengan Ractive untuk menentukan elemen HTML untuk menerima data yang akan ditampilkan, tetapi cara paling sederhana untuk melakukannya adalah dengan menambahkan ID ke elemen. Saya biasanya menggunakan ID "root" untuk tujuan ini. Kita akan segera melihat bagaimana itu digunakan ketika Ractive diinisialisasi. Bagi mereka yang penasaran ada cara lain untuk menentukan elemen root.

Elemen skrip yang agak canggung dengan type="text/html" adalah trik cerdas untuk mendapatkan potongan HTML yang dimuat oleh browser tanpa diurai atau dirender, karena browser mengabaikan skrip dengan tipe yang tidak diketahui. Konten skrip adalah templat seperti Kumis/Stang (meskipun Ractive memang memiliki beberapa ekstensi).

Kami pertama-tama menulis kode template dengan asumsi bahwa kami memiliki akses ke array keterampilan. Kami menggunakan direktif kumis {{#each}} untuk mendefinisikan iterasi. Di dalam direktif, elemen saat ini dapat diakses sebagai this . Sekali lagi, kami berasumsi bahwa variabel keterampilan menyimpan array string, jadi kami hanya merendernya dengan kumis interpolasi {{this}} .

Oke, itu HTMLnya. Tapi bagaimana dengan JavaScript? Di situlah "keajaiban" terjadi yang memasok data ke template::

 (function () { var skills = DB.skills, developers = DB.developers; var app = new Ractive({ el: '#root', template: '#tpl-app', data: { skills: _.keys(DB.skills) } }); }());

Mengesankan, bukan? Hanya dalam 10 baris kode itu kita dapat:

  1. "Ambil" data dari "DB".
  2. Instansiasi aplikasi Ractive baru.
  3. Katakan itu untuk membuat bagian dalam elemen dengan .
  4. Katakan untuk menggunakan elemen skrip dengan untuk mendapatkan template (ada cara lain untuk melakukannya juga).
  5. Lewati data awal (kita akan melihat cara mengubahnya saat runtime), atau "lingkup" jika Anda terbiasa dengan terminologi Angular.
  6. Gunakan metode keys lodash untuk mendapatkan nama keterampilan yang kami gunakan sebagai kunci objek di "DB".

Jadi pada dasarnya dengan skrip ini kami memberi tahu kerangka kerja apa yang harus dilakukan, tetapi bukan bagaimana melakukannya. Template menyatakan bagaimana, yang menurut saya pribadi sangat menakjubkan dan alami.

Semoga Anda mulai mendapatkan idenya, jadi sekarang mari kita terapkan sesuatu yang lebih berguna di atas apa yang kita miliki.

Pencarian Keterampilan

Halaman pencarian tentu saja membutuhkan kolom pencarian. Dan kami ingin itu memberikan kemampuan interaktif di mana saat pengguna mengetik di kotak pencarian, daftar keterampilan yang disaring hanya mencakup yang berisi substring yang dimasukkan (dengan pemfilteran yang peka huruf besar-kecil).

Seperti biasa dengan Ractive, kita mulai dengan mendefinisikan template (sambil memikirkan variabel konteks baru mana yang akan dibutuhkan, dan apa yang akan berubah terkait dengan pengelolaan data):

 <div class="container"> <h1>Toptal Search</h1> <div></div> </div> <!-- THIS IS THE SMALL SNIPPET OF TEMPLATE CODE --> <script type="text/html"> <!-- HERE'S OUR SEARCH BOX --> <div class="row"> <form class="form-horizontal col-xs-6 col-xs-offset-6"> <input type="search" class="form-control" value="{{ skillFilter }}" placeholder="Type part of the skill name here"> </form> </div> <hr> <!-- NOW INSTEAD OF DISPLAYING ALL SKILLS, WE INVOKE A TO-BE-CREATED JAVASCRIPT skills() FUNCTION THAT WILL FILTER THE SKILL LIST DOWN TO THOSE THAT MATCH THE TEXT ENTERED BY THE USER --> <div class="row"> {{#each skills()}} <span class="col-xs-3"> <a href="#" class="label label-primary">{{this}}</a> </span> {{/each}} </div> </script>

Tidak begitu banyak perubahan, tetapi masih cukup banyak untuk dipelajari.

Pertama, kami telah menambahkan <div> baru yang berisi kotak pencarian kami. Cukup jelas kami ingin menghubungkan input itu ke beberapa variabel (kecuali jika Anda nostalgia tentang hari-hari sup jQuery lama yang bagus). Ractive mendukung apa yang disebut pengikatan dua arah, yang berarti bahwa kode JS Anda dapat mengambil nilai tanpa perlu membacanya secara manual dari DOM. Dalam kasus kami, ini dicapai dengan menggunakan interpolasi mustache value="{{ skillFilter }}" . Ractive memahami bahwa kita ingin mengikat variabel ini ke atribut nilai dari input. Jadi ia mengawasi input untuk kita dan secara otomatis memperbarui variabel. Cukup rapi hanya dengan 1 baris HTML.

Kedua, seperti yang dijelaskan dalam komentar di cuplikan kode di atas, sekarang alih-alih menampilkan semua keterampilan, kita akan membuat fungsi skills() JS yang akan memfilter daftar keterampilan dan hanya mengembalikan yang cocok dengan teks yang dimasukkan oleh pengguna:

 // store skill list in a variable outside of Ractive scope var skillNames = _.keys(DB.skills); var app = new Ractive({ el: '#root', template: '#tpl-app', data: { // initializing the context variable is not strictly // required, but it is generally considered good practice skillFilter: null, // Define the skills() function right in our data object. // Function is available to our template where we call it. skills: function() { // Get the skillFilter variable from the Ractive instance // (available as 'this'). // NOTE WELL: Our use of a getter here tells Ractive that // our function has a *dependency* on the skillFilter // value, so this is significant. var skillFilter = this.get('skillFilter'); if (!skillFilter) { return skillNames; } skillFilter = new RegExp(_.escapeRegExp(skillFilter), 'i') return _.filter(skillNames, function(skill) { return skill.match(skillFilter); }); } } });

Meskipun ini bersih dan mudah diterapkan, Anda mungkin bertanya-tanya tentang bagaimana pengaruhnya terhadap kinerja. Maksud saya, kita akan memanggil fungsi setiap kali? Nah, setiap kali apa? Ractive cukup pintar untuk hanya merender ulang bagian template (dan memanggil fungsi apa pun darinya) ketika dependensi (variabel) berubah (Ractive tahu kapan itu terjadi berkat penggunaan setter).

Kebetulan, bagi mereka yang tertarik untuk mengambil langkah ini lebih jauh, ada juga cara yang lebih elegan untuk melakukan ini menggunakan properti yang dihitung, tetapi saya akan membiarkannya untuk Anda mainkan sendiri jika Anda mau.

Halaman Hasil

Sekarang setelah kita memiliki daftar keterampilan yang dapat dicari, mari beralih ke tampilan hasil di mana daftar pengembang yang cocok akan ditampilkan.

Beralih ke dan dari Tampilan Keterampilan

Jelas ada banyak cara agar ini bisa diterapkan. Saya memilih pendekatan karena ada dua pandangan berbeda tergantung pada apakah keterampilan telah dipilih atau tidak. Jika demikian, kami menampilkan daftar pengembang yang cocok; jika tidak, kami menunjukkan daftar keterampilan dan kotak pencarian.

Jadi, sebagai permulaan, ketika pengguna memilih (yaitu, mengklik) nama keterampilan, daftar keterampilan harus disembunyikan dan nama keterampilan harus ditampilkan sebagai judul halaman. Sebaliknya, pada tampilan skill yang dipilih, perlu ada cara untuk menutup tampilan itu dan kembali ke daftar skill.

Inilah langkah pertama kami di jalan ini:

 <script type="text/html"> <!-- PARTIAL IS A NEW CONCEPT HERE --> {{#partial skillsList}} <div class="row"> <form class="form-horizontal col-xs-6 col-xs-offset-6"> <input type="search" class="form-control" value="{{ skillFilter }}" placeholder="Type part of the skill name here"> </form> </div> <hr> <div class="row"> {{#each skills()}} <span class="col-xs-3"> <!-- MAKE OUR SKILLS CLICKABLE, USING PROXY EVENTS --> <a href="#" class="label label-primary" on-click="select-skill:{{this}}">{{this}}</a> </span> {{/each}} </div> {{/partial}} {{#partial skillView}} <h2> <!-- DISPLAY SELECTED SKILL AS HEADING ON THE PAGE --> {{ currentSkill }} <!-- CLOSE BUTTON TAKES USER BACK TO SKILLS LIST --> <button type="button" class="close pull-right" on-click="deselect-skill">&times; CLOSE</button> </h2> {{/partial}} <!-- PARTIALS ARE NOT IN THE VIEW UNTIL WE EXPLICITLY INCLUDE THEM, SO INCLUDE THE PARTIAL RELEVANT TO THE CURRENT VIEW. --> {{#if currentSkill}} {{> skillView}} {{else}} {{> skillsList}} {{/if}} </script>

OK, ada BANYAK yang terjadi di sini.

Pertama, untuk mengakomodasi penerapan ini sebagai dua tampilan berbeda, saya memindahkan semua yang kami miliki sejauh ini (yaitu, tampilan daftar) ke sesuatu yang disebut sebagian. Sebagian pada dasarnya adalah potongan kode template yang akan kita sertakan di tempat yang berbeda (segera).

Kemudian, kami ingin membuat keterampilan kami dapat diklik, dan ketika diklik kami ingin menavigasi ke tampilan keterampilan yang sesuai. Untuk ini, kami menggunakan sesuatu yang disebut peristiwa proxy, di mana kami bereaksi terhadap peristiwa fisik (di-klik, nama yang dapat dimengerti oleh Ractive) dan memproksikannya ke peristiwa logis (pilih-keterampilan, nama apa pun yang kami sebut itu ) menyampaikan argumen (seperti yang mungkin Anda ingat ini adalah singkatan dari nama keterampilan di sini).

(FYI, ada sintaks alternatif dari pemanggilan metode untuk mencapai hal yang sama.)

Selanjutnya, kita asumsikan (sekali lagi) bahwa kita akan memiliki variabel bernama currentSkill yang akan memiliki nama skill yang dipilih (jika ada), atau akan kosong jika tidak ada skill yang dipilih. Jadi kami mendefinisikan bagian lain yang menunjukkan nama keterampilan saat ini, dan juga memiliki tautan "TUTUP" yang harus membatalkan pilihan keterampilan.

Untuk JavaScript, tambahan utama adalah kode untuk berlangganan ke acara pilih-keterampilan dan batalkan pilihan-keterampilan, perbarui currentSkill (dan skillFilter ) yang sesuai:

 var app = new Ractive({ el: '#root', template: '#tpl-app', data: { skillFilter: null, currentSkill: null, // INITIALIZE currentSkill TO null // skills function remains unchanged skills: function() { var skillFilter = this.get('skillFilter'); if (!skillFilter) { return skillNames; } skillFilter = new RegExp(_.escapeRegExp(skillFilter), 'i') return _.filter(skillNames, function(skill) { return skill.match(skillFilter); }); } } }); // SUBSCRIBE TO LOGICAL EVENT select-skill app.on('select-skill', function(event, skill) { this.set({ // SET currentSkill TO THE SKILL SELECTED BY THE USER currentSkill: skill, // RESET THE SEARCH FILTER skillFilter: null }); }); // SUBSCRIBE TO LOGICAL EVENT deselect-skill app.on('deselect-skill', function(event) { this.set('currentSkill', null); // CLEAR currentSkill });

Mencantumkan Pengembang untuk Setiap Keterampilan

Setelah menyiapkan tampilan baru untuk keterampilan, sekarang kita dapat menambahkan beberapa daging — daftar pengembang sebenarnya yang kita miliki untuk daftar itu. Untuk itu, kami memperluas sebagian untuk tampilan ini sebagai berikut:

 {{#partial skillView}} <h2> {{ currentSkill }} <button type="button" class="close pull-right" on-click="deselect-skill">&times; CLOSE</button> </h2> {{#each skillDevelopers(currentSkill)}} <div class="panel panel-default"> <div class="panel-body"> {{ this.name }} </div> </div> {{/each}} {{/partial}}

Semoga pada titik ini, Anda merasakan apa yang terjadi di sini: kami telah menambahkan bagian iterasi baru ke parsial skillView kami yang mengulangi hasil fungsi skillDevelopers baru yang akan kami tulis selanjutnya. Untuk setiap developer dalam array (dikembalikan oleh fungsi skillDevelopers itu), kami merender panel dan menampilkan nama developer. Perhatikan bahwa saya dapat menggunakan bentuk implisit {{name}} di sini dan Ractive akan menemukan atribut yang tepat dengan mencari rantai konteks mulai dari konteks saat ini (yang dalam kasus kami adalah objek pengembang yang terikat oleh {{#each}} ), tetapi Saya lebih suka menjadi eksplisit. Informasi lebih lanjut tentang konteks dan referensi tersedia di dokumentasi Ractive.

Dan inilah implementasi dari fungsi skillDevelopers() :

 skillDevelopers: function(skill) { // GET THE SKILL OBJECT FROM THE “DB” skill = skills[skill]; // SAFETY CHECK, RETURN EARLY IN CASE OF UNKNOWN SKILL NAME if (!skill) { return; } // MAP THE DEVELOPER'S IDs (SLUGS) TO THE // ACTUAL DEVELOPER DETAIL OBJECTS return _.map(skill.developers, function(slug) { return developers[slug]; }); }

Memperluas Entri untuk Setiap Pengembang

Sekarang kami memiliki daftar pengembang yang berfungsi, saatnya untuk menambahkan lebih banyak detail, dan tentu saja foto yang bagus:

 {{#partial skillView}} <h2> {{ currentSkill }} <button type="button" class="close pull-right" on-click="deselect-skill">&times; CLOSE</button> </h2> {{#each skillDevelopers(currentSkill)}} <div class="panel panel-default"> <div class="panel-body media"> <div class="media-left"> <!-- ADD THE PHOTO --> <img class="media-object img-circle" width="64" height="64" src="{{ this.photo }}" alt="{{ this.name }}"> </div> <div class="media-body"> <!-- MAKE THE DEVELOPER'S NAME A HYPERLINK TO THEIR PROFILE --> <a class="h4 media-heading" href="{{ this.url }}" target="_blank"> {{ this.name }}</a> <!-- ADD MORE DETAILS (FROM THEIR PROFILE) --> <p>{{ this.desc }}</p> </div> </div> </div> {{/each}} {{/partial}}

Tidak ada yang baru di sini dari sisi Ractive, tetapi penggunaan fitur Bootstrap yang sedikit lebih berat.

Menampilkan Daftar Keterampilan Pengembang yang Dapat Diklik

Kami telah membuat kemajuan yang baik sejauh ini, tetapi satu fitur yang masih hilang adalah sisi lain dari hubungan pengembang keterampilan; yaitu, kami ingin menampilkan setiap keterampilan pengembang dan kami ingin setiap keterampilan tersebut menjadi tautan yang dapat diklik yang membawa kami ke tampilan hasil untuk keterampilan tersebut.

Tapi tunggu… Aku yakin kita sudah memiliki hal yang sama persis di daftar skill. Ya, sebenarnya, kami melakukannya. Itu ada dalam daftar keterampilan yang dapat diklik, tetapi itu berasal dari susunan yang berbeda dari rangkaian keterampilan masing-masing pengembang. Namun ini cukup mirip sehingga merupakan tanda yang jelas bagi saya bahwa kita harus menggunakan kembali potongan HTML itu. Dan menuju tujuan itu, sebagian adalah teman kita.

(Catatan: Ractive juga memiliki pendekatan yang lebih maju untuk potongan tampilan yang dapat digunakan kembali, yang dikenal sebagai komponen. Mereka benar-benar sangat berguna, tetapi demi kesederhanaan, kami tidak akan membahasnya sekarang.)

Jadi, inilah cara kami melakukannya menggunakan parsial (dan perhatikan, kebetulan, bahwa kami dapat menambahkan fungsi ini tanpa menambahkan satu baris kode JavaScript!):

 <!-- MAKE THE CLICKABLE SKILL LINK INTO ITS OWN “skill” PARTIAL --> {{#partial skill}} <a href="#" class="label label-primary" on-click="select-skill:{{this}}">{{this}}</a> {{/partial}} {{#partial skillsList}} <div class="row"> <form class="form-horizontal col-xs-6 col-xs-offset-6"> <input type="search" class="form-control" value="{{ skillFilter }}" placeholder="Type part of the skill name here"> </form> </div> <hr> <div class="row"> {{#each skills()}} <!-- USE THE NEW “skill” PARTIAL --> <span class="col-xs-3">{{> skill}}</span> {{/each}} </div> {{/partial}} {{#partial skillView}} <h2> {{ currentSkill }} <button type="button" class="close pull-right" on-click="deselect-skill">&times; CLOSE</button> </h2> {{#each skillDevelopers(currentSkill)}} <div class="panel panel-default"> <div class="panel-body media"> <div class="media-left"> <img class="media-object img-circle" width="64" height="64" src="{{ this.photo }}" alt="{{ this.name }}"> </div> <div class="media-body"> <a class="h4 media-heading" href="{{ this.url }}" target="_blank">{{ this.name }}</a> <p>{{ this.desc }}</p> <p> <!-- ITERATE OVER THE DEVELOPER'S SKILLS --> {{#each this.skills}} <!-- REUSE THE NEW “skill” PARTIAL TO DISPLAY EACH DEVELOPER SKILL AS A CLICKABLE LINK --> {{> skill}}&nbsp; {{/each}} </p> </div> </div> </div> {{/each}} {{/partial}}

Saya sudah memiliki daftar keterampilan yang dilampirkan ke objek pengembang yang kami ambil dari "DB", jadi saya hanya mengubah sedikit template: Saya memindahkan baris yang membuat label keterampilan menjadi parsial dan menggunakan parsial ini di mana baris itu awalnya.

Kemudian, ketika saya mengulangi keterampilan pengembang, saya dapat menggunakan kembali bagian baru yang sama ini untuk menampilkan masing-masing keterampilan tersebut sebagai tautan yang dapat diklik juga. Selain itu, ini juga memproksi acara pilih keterampilan jika Anda ingat, melewati nama keterampilan yang sama. Ini berarti kami dapat memasukkan ini di mana saja (memiliki konteks yang tepat) dan kami akan mendapatkan label yang dapat diklik yang mengarah ke tampilan keterampilan!

Sentuhan Terakhir — Prapemuat

Oke, kami sekarang memiliki aplikasi fungsional dasar. Ini bersih dan bekerja cepat, tetapi masih membutuhkan waktu untuk memuat. (Dalam kasus kami, ini sebagian karena kami menggunakan sumber yang tidak digabungkan dan tidak diperkecil, tetapi dalam aplikasi dunia nyata mungkin ada alasan signifikan lainnya, seperti pemuatan data awal).

Jadi sebagai salah satu langkah terakhir, saya akan menunjukkan trik rapi untuk menambahkan animasi pramuat yang akan dihapus segera setelah Ractive merender aplikasi kita:

 <div class="container"> <h1>Toptal Search</h1> <div> <div class="progress"> <div class="progress-bar progress-bar-striped active"> Loading... </div> </div> </div> </div>

Jadi apa keajaiban di sini? Ini sebenarnya cukup sederhana. Saya menambahkan beberapa konten (ini adalah bilah kemajuan animasi Bootstrap, tetapi bisa berupa GIF animasi, atau apa pun) langsung ke elemen root kami. Saya pikir ini cukup pintar — saat skrip kami sedang memuat, pengguna melihat indikator pemuatan (karena tidak memiliki ketergantungan pada JavaScript, itu dapat segera ditampilkan). Namun, segera setelah aplikasi Ractive diinisialisasi, Ractive akan menimpa konten elemen root (dan dengan demikian menghapus animasi pramuat) dengan template yang dirender. Dengan begitu, kami dapat mencapai efek ini hanya dengan sepotong HTML statis dan 0 baris logika. Saya pikir itu cukup keren.

Kesimpulan

Pikirkan tentang apa yang telah kita capai di sini dan betapa mudahnya kita mencapainya. Kami memiliki aplikasi yang cukup komprehensif: ini menunjukkan daftar keterampilan, memungkinkan pencarian melalui mereka dengan cepat (dan bahkan mendukung pembaruan interaktif daftar keterampilan saat pengguna mengetik di kotak pencarian), memungkinkan menavigasi ke keterampilan tertentu dan kembali, dan daftar pengembang untuk setiap keterampilan yang dipilih. Selanjutnya, kita dapat mengklik keterampilan apa pun yang terdaftar oleh pengembang mana pun untuk membawa kita ke daftar pengembang dengan keterampilan itu. Dan semua itu dengan kurang dari 80 baris HTML dan kurang dari 40 baris JavaScript. Menurut saya, itu cukup mengesankan dan berbicara banyak tentang kekuatan, keanggunan, dan kesederhanaan Ractive.

Versi aplikasi yang berfungsi tersedia online di sini dan kode sumber lengkapnya tersedia untuk publik dan tersedia di sini.

Tentu saja, kami baru saja menggores permukaan dalam artikel ini tentang apa yang mungkin terjadi dengan kerangka kerja Ractive. Jika Anda menyukai apa yang telah Anda lihat sejauh ini, saya sangat menganjurkan Anda untuk memulai pengaturan 60 detik Ractive dan mulai menjelajahi sendiri semua yang ditawarkan Ractive.