Backbone harus mengandalkan underscore.js untuk digunakan. Itu harus menggunakan fungsi di bawah untuk menyelesaikan operasi dasar mengakses elemen halaman dan elemen pemrosesan.
Catatan: Backbone bekerja dengan baik dengan perpustakaan JS lainnya, jadi ini adalah perpustakaan, bukan kerangka kerja.
Underscore tidak memperluas objek asli, tetapi memanggil metode _ () untuk merangkum. Setelah enkapsulasi selesai, objek JS menjadi objek garis bawah. Anda juga dapat memperoleh data dalam objek JS asli melalui metode nilai () dari objek underscore. (jQuery memperoleh objek jQuery melalui metode $ ())
Underscore memiliki lebih dari 60 fungsi secara total. Menurut berbagai objek pemrosesan, itu dapat dibagi menjadi lima modul utama: kelas pengumpulan, kelas array, kelas fungsi fungsional, kelas objek, dan kelas fungsi alat.
Underscore Template () Fungsi Deskripsi:
Fungsi ini berisi tiga templat:
(1) < % %>: berisi kode logis dan tidak akan ditampilkan setelah rendering.
(2) < %= %>: Jenis data, tampilkan data setelah rendering.
(3) < %- %>: Konversi tag HTML ke string umum untuk menghindari serangan kode.
Format panggilan:
_.template (templateString, [data], [pengaturan])
Tidak ada pengikatan data dua arah yang diimplementasikan.
1. Enkapsulasi objek menggarisbawahi
Underscore tidak meluas dalam prototipe objek JavaScript asli, tetapi merangkum data dalam objek khusus seperti jQuery (selanjutnya disebut sebagai "objek underscore").
Anda bisa mendapatkan data JavaScript asli dengan memanggil metode nilai () dari objek underscore, misalnya:
// Tentukan objek bawaan JavaScript var jsdata = {name: 'Data'} // Buat objek sebagai objek underscore melalui metode _ () // Prototipe objek underscoredata berisi semua metode yang ditentukan dalam underscore. Anda dapat menggunakan var underscoredata = _ (jsdata); // Dapatkan data asli melalui metode nilai, yaitu, jsdata underscoredata.value ();2. Panggilan Prioritas ke JavaScript 1.6 Metode bawaan
Ada banyak metode di garis bawah yang telah dimasukkan dalam spesifikasi dalam JavaScript 1.6. Oleh karena itu, di dalam objek bawah, metode bawaan yang disediakan oleh lingkungan host (jika lingkungan host telah mengimplementasikan metode ini) akan dipanggil terlebih dahulu untuk meningkatkan efisiensi eksekusi fungsi.
Untuk lingkungan host yang tidak mendukung JavaScript 1.6, garis bawah akan mengimplementasikannya dengan caranya sendiri, dan untuk pengembang, ini sepenuhnya transparan.
Lingkungan host yang disebutkan di sini mungkin lingkungan yang menjalankan Node.js atau browser klien.
3. Ubah namespace
Underscore menggunakan _ (underscore) secara default untuk mengakses dan membuat objek, tetapi nama ini mungkin tidak mematuhi spesifikasi penamaan kami atau dapat dengan mudah menyebabkan konflik penamaan.
Kita dapat mengubah nama garis bawah melalui metode noconflict () dan mengembalikan nilai sebelum variabel _ (garis bawah), misalnya: misalnya:
<script type = "text/javascript"> var _ = 'custom variable'; </script> <script type = "Text/JavaScript" src = "Underscore/Underscore-min.js"> </script> <script type = "text/javascript"> // underscore objek console.dir (_); // Ubah nama objek underscore kepada kami, dan kemudian akses dan buat objek underscore melalui kami var us = _.noconflict (); // output "variabel khusus" console.dir (_); </script>
4. Operasi rantai
Ingat bagaimana kami melakukan operasi tautan di jQuery? Misalnya:
$ ('a') .css ('posisi', 'relatif') .attr ('href', '#') .show ();Underscore juga mendukung operasi rantai, tetapi Anda perlu memanggil metode rantai () untuk menyatakan:
var arr = [10, 20, 30]; _ (arr) .chain () .map (function (item) {return item ++;}) .first () .value ();Jika metode rantai () dipanggil, underscore akan merangkum metode yang dipanggil dalam penutupan, merangkum nilai pengembalian ke dalam objek garis bawah dan pengembalian:
// Ini adalah fungsi utama dalam garis bawah untuk mengimplementasikan operasi rantai. Ini merangkum nilai pengembalian ke dalam objek garis bawah baru dan memanggil metode rantai () lagi untuk memberikan dukungan untuk fungsi berikutnya dalam rantai metode. var result = fungsi (obj, rantai) {rantai pengembalian? _ (obj) .chain (): obj; }5. Perluas Underscore
Kami dapat dengan mudah menyampaikan metode khusus ke dalam garis bawah melalui metode mixin (), misalnya:
_.Mixin ({Method1: function (objek) {// TODO}, method2: function (arr) {// TODO}, method3: function (fn) {// TODO}});Metode -metode ini ditambahkan ke objek prototipe underscore, yang dapat digunakan oleh semua objek garis bawah yang dibuat, dan mereka menikmati lingkungan yang sama dengan metode lainnya.
6. Lintasi koleksi
Setiap metode () dan peta () adalah dua metode yang paling umum digunakan. Mereka terbiasa mengulangi koleksi (array atau objek) dan memproses setiap elemen dalam koleksi secara bergantian, misalnya:
var arr = [1, 2, 3]; _ (arr) .map (fungsi (item, i) {arr [i] = item + 1;}); var obj = {pertama: 1, kedua: 2} _ (obj) .each (function (value, key) {return obj [key] = value + 1;});Metode MAP () memiliki peran dan parameter yang sama seperti setiap metode (), tetapi mencatat hasil yang dikembalikan oleh setiap fungsi iterasi ke array baru dan kembali.
7. Fungsi Throttling
Fungsi throttling mengacu pada mengendalikan frekuensi eksekusi atau interval suatu fungsi (seperti gerbang yang mengontrol aliran air). Underscore menyediakan dua metode: debounce () dan throttle () untuk fungsi throttling.
Untuk menggambarkan dua metode ini lebih jelas, asumsikan bahwa kita perlu menerapkan dua persyaratan:
Persyaratan 1: Ketika pengguna memasukkan kriteria pencarian di kotak teks, kata kunci yang cocok secara otomatis ditanyakan dan diminta kepada pengguna (seperti saat memasukkan kata kunci pencarian di TMall)
Pertama, analisis persyaratan pertama. Kami dapat mengikat acara Keypress dari kotak teks. Saat konten kotak input berubah, query kata kunci yang cocok dan tampilkan. Misalkan saya ingin meminta "Windows Phone", yang berisi 13 karakter, dan hanya butuh 1 detik bagi saya untuk menyelesaikan input (tampaknya agak cepat, itulah artinya), lalu dalam 1 detik ini, metode kueri disebut 13 kali. Ini adalah hal yang sangat menakutkan, dan jika tmall diimplementasikan seperti ini, saya khawatir itu akan mati sebelum hari lajang (tentu saja, itu tidak rapuh, tetapi jelas bukan solusi terbaik)
Pendekatan yang lebih baik adalah menanyakan kata kunci yang cocok ketika pengguna telah selesai memasukkan atau sedang menunggu prompt (mungkin dia terlalu malas untuk memasukkan konten berikut).
Akhirnya kami menemukan bahwa dalam kedua kasus yang kami harapkan, pengguna untuk sementara waktu akan menghentikan input, jadi kami memutuskan untuk menanyakan setelah pengguna berhenti input selama 200 milidetik (jika pengguna terus mengetik konten, maka kami pikir ia mungkin sangat jelas tentang kata kunci yang ia inginkan, jadi tunggu dan minta dia lagi)
Pada saat ini, menggunakan fungsi debounce () di garis bawah, kami dapat dengan mudah menerapkan persyaratan ini:
<input type = "text" id = "search" name = "search" /> <script type = "text /javaScript"> var query = _ (function () {// operasi kueri di sini}). debounce (200); $ ('#Search'). Bind ('Keypress', kueri); </script>Anda dapat melihat bahwa kode kami sangat ringkas, dan kontrol pelambatan telah diimplementasikan dalam metode Debounce (). Kami hanya mengatakan bahwa jika fungsi kueri belum dipanggil dalam waktu 200 milidetik, kami akan menjalankan operasi kueri kami, dan kemudian mengikat fungsi kueri ke acara Keypress di kotak input.
Bagaimana fungsi kueri terjadi? Ketika kami memanggil metode Debounce (), kami akan melewati fungsi yang melakukan operasi kueri dan waktu (milidetik). Metode Debounce () akan mencekik fungsi berdasarkan waktu yang kita lewati, dan mengembalikan fungsi baru (mis. Fungsi kueri). Kita dapat memanggil fungsi kueri dengan keyakinan dan keberanian, dan metode Debounce () akan membantu kita mengendalikannya sesuai kebutuhan.
Persyaratan 2: Ketika pengguna menyeret scrollbar browser, hubungi antarmuka server untuk memeriksa apakah ada konten baru
Mari kita analisis persyaratan kedua. Kami dapat mengikat metode kueri ke acara Window.onscroll, tetapi ini jelas bukan praktik yang baik, karena pengguna menyeret scrollbar sekali dan dapat memicu lusinan atau bahkan ratusan acara Onscroll.
Bisakah kita menggunakan metode Debounce () di atas untuk melakukan kontrol pelambatan? Ketika pengguna selesai menyeret scrollbar, lalu meminta konten baru? Tetapi ini tidak konsisten dengan persyaratan, dan pengguna berharap untuk melihat perubahan konten baru selama proses seret.
Jadi kami memutuskan untuk melakukan ini: Ketika pengguna menyeret, interval antara setiap dua pertanyaan tidak kurang dari 500 milidetik, jika pengguna menyeret selama 1 detik, ini dapat memicu 200 acara onscroll, tetapi kami hanya melakukan 2 kueri paling banyak.
Menggunakan metode throttle () di garis bawah, kami juga dapat dengan mudah menerapkan persyaratan ini:
<script type = "text/javascript"> var query = _ (function () {// Operasi kueri di sini}). Throttle (500); $ (window) .bind ('gulir', kueri); </script>Kode ini masih sangat ringkas, karena di dalam metode throttle (), semua kontrol yang telah kami terapkan untuk.
Anda mungkin telah menemukan bahwa dua metode debounce () dan throttle () sangat mirip (termasuk metode panggilan dan nilai pengembalian), tetapi fungsinya berbeda.
Mereka semua digunakan untuk pelambatan fungsi, dan fungsi kontrol tidak sering disebut, menyimpan sumber daya klien dan server.
Metode Debounce () berfokus pada interval antara eksekusi fungsi, yaitu, waktu panggilan fungsi dua kali tidak bisa kurang dari waktu yang ditentukan.
Metode throttle () lebih berfokus pada frekuensi eksekusi fungsi, yaitu fungsi hanya akan dipanggil sekali dalam frekuensi yang ditentukan.
8. Analisis Template
Underscore menyediakan fungsi penguraian template yang ringan yang membantu kita mengatur struktur dan logika halaman secara efektif.
Saya akan memperkenalkannya dengan contoh:
<!-- Used to display rendered tags --> <ul id="element"></ul> <!-- Define a template and put the template content into a script tag --> <script type="text/template" id="tpl"> <% for(var i = 0; i < list.length; i++) { %> <% var item = list[i] %> <li> <span><%=item.firstName%> <%= item.LastName%> </span> <span> <%-item.city%> </span> </li> <%}%> </script> <script type = "text/javascript" src = "underscore/underscore-min.js"> </skrip> <script type = "text/javascript"> $ ('#elemen'), tpl = $ ('#tpl'). html (); // Buat data, yang mungkin merupakan data var yang Anda dapatkan dari server = {list: [{firstName: '<a href = "#"> zhang </a>', lastname: 'san', city: 'shanghai'}, {firstName: 'li', lastname: 'si', city: '<a href = "' '' '#' ''#'' ''#'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' 'yang” yang ”” yang ”” ”yang”#' 'Wang', LastName: 'Wu', City: 'Guangzhou'}, {FirstName: 'Zhao', LastName: 'Liu', City: 'Shenzhen'}]} // Parse Template, kembalikan konten yang di -parsing var html = _.template (tpl, data); // mengisi konten parsed ke elemen rendering elemen.html (html); </script>Dalam contoh ini, kami memasukkan konten template ke dalam tag <script>, Anda mungkin telah memperhatikan bahwa tipe tag adalah teks/templat alih -alih teks/javascript, karena tidak dapat dijalankan secara langsung sebagai skrip JavaScript.
Saya juga menyarankan agar Anda memasukkan konten template di <script> karena jika Anda menulisnya di <div> atau tag lain, mereka dapat ditambahkan ke pohon DOM untuk parsing (bahkan jika Anda menyembunyikan tag ini, itu tidak akan dihindari).
_.Template Template Function hanya dapat menguraikan 3 jenis tag template (ini jauh lebih sederhana daripada Smarty dan JSTL):
< % %>: Dulu berisi kode JavaScript yang akan dieksekusi saat data diberikan.
< %= %>: Digunakan untuk mengeluarkan data, itu bisa berupa variabel, atribut objek, atau panggilan fungsi (untuk mengeluarkan nilai pengembalian fungsi).
< %- %>: Digunakan untuk mengeluarkan data, dan mengonversi karakter HTML yang terkandung dalam data ke dalam bentuk entitas (misalnya, itu mengonversi kutipan ganda menjadi bentuk), untuk menghindari serangan XSS.
Ketika kami ingin menampilkan HTML dalam data sebagai teks, kami sering menggunakan tag < %- %>.
Underscore juga memungkinkan Anda untuk memodifikasi 3 bentuk tag ini. Jika kita ingin menggunakan { % %}, { %= %}, { %- %} sebagai tag, kita dapat melakukannya dengan memodifikasi Templatesettings, seperti ini:
_.templatesettings = {evaluasi: // {%([/s/s]+?)/%/}/g, interpolate: // {%= ([/s/s]+?)/%/}/g, Escape: // {%-([/s]+?)%/}/g}Dalam contoh ini, kami meneruskan konten templat dan data untuk diisi ke metode templat, yang akan diproses dalam urutan berikut:
(1) Menguras konten template ke dalam JavaScript yang dapat dieksekusi (tag template parse)
(2) Ubah ruang lingkup javascript yang diuraikan ke objek data yang kami lewati dengan pernyataan, yang memungkinkan kami untuk secara langsung mengakses properti objek data melalui variabel dalam templat.
(3) Jalankan JavaScript Parsed (Mengisi Data ke Template)
(4) Kembalikan hasilnya setelah eksekusi
Kita sering menghadapi situasi di mana metode templat disebut beberapa kali untuk membuat data ke templat yang sama.
Misalkan kita memiliki daftar paging, dan setiap bagian data dalam daftar diterjemahkan melalui templat. Ketika pengguna memasuki halaman berikutnya, kami akan mendapatkan data dari halaman berikutnya dan render ulang. Faktanya, templatnya sama setiap kali diterjemahkan, tetapi semua proses pemrosesan template yang dijelaskan sekarang akan selalu dieksekusi.
Faktanya, metode template dari garis bawah memberikan cara menelepon yang lebih efisien. Kami memodifikasi dua kalimat terakhir dalam kode di atas menjadi:
// parsing templat, kembalikan konten parsed var render = _.template (tpl); var html = render (data); // mengisi konten yang diuraikan ke elemen render elemen.html (html);
Anda akan menemukan perbedaan halus: Ketika kami memanggil metode template, kami hanya melewati konten templat, tetapi bukan data. Pada saat ini, metode template akan menguraikan konten templat, menghasilkan kode javascript yang dapat dieksekusi yang dieksekusi, dan mengembalikan fungsi, dan badan fungsi adalah javascript parsed. Oleh karena itu, ketika kami memanggil fungsi ini untuk membuat data, kami menghilangkan tindakan parsing template.
Anda harus menyimpan fungsi yang dikembalikan (seperti saya menyimpannya di variabel render), dan kemudian membuat data dengan memanggil fungsi, terutama jika template yang sama dapat diterjemahkan beberapa kali. Melakukan hal itu dapat meningkatkan efisiensi eksekusi (peningkatan spesifik harus tergantung pada panjang dan kompleksitas template Anda, tetapi itu adalah kebiasaan yang baik).