


Analisis ringkas kaedah pelaksanaan asas enjin templat JavaScript_Pengetahuan asas
Templat memisahkan data dan pembentangan, menjadikan logik dan kesan pembentangan lebih mudah diselenggara. Menggunakan objek Fungsi JavaScript, bina enjin penukaran templat yang sangat mudah langkah demi langkah
Pengenalan Templat
Templat biasanya merujuk kepada teks yang dibenamkan dengan beberapa jenis kod bahasa pengaturcaraan dinamik Data dan templat boleh digabungkan dalam beberapa bentuk untuk menghasilkan hasil yang berbeza. Templat biasanya digunakan untuk menentukan bentuk paparan, yang boleh menjadikan persembahan data lebih kaya dan lebih mudah untuk diselenggara. Sebagai contoh, berikut ialah contoh templat:
<ul> <% for(var i in items){ %> <li class='<%= items[i].status %>'><%= items[i].text %></li> <% } %> </ul>
Jika terdapat data item berikut:
items:[ { text: 'text1' ,status:'done' }, { text: 'text2' ,status:'pending' }, { text: 'text3' ,status:'pending' }, { text: 'text4' ,status:'processing' } ]
Dengan menggabungkannya dalam beberapa cara, kod Html berikut boleh dijana:
<ul> <li class='done'>text1<li> <li class='pending'>text2<li> <li class='pending'>text3<li> <li class='processing'>text4<li> </ul>
Jika anda ingin mencapai kesan yang sama tanpa menggunakan templat, iaitu, untuk memaparkan data di atas sebagai hasilnya, anda perlu melakukan perkara berikut:
var temp = '<ul>'; for(var i in items){ temp += "<li class='" + items[i].status + "'>" + items[i].text + "</li>"; } temp += '</ul>';
Dapat dilihat bahawa menggunakan templat mempunyai faedah berikut:
Penulisan html yang dipermudahkan
Mempunyai lebih kawalan ke atas pembentangan data melalui elemen pengaturcaraan (seperti gelung dan cawangan bersyarat)
Mengasingkan data dan paparan, menjadikan logik paparan dan kesan lebih mudah untuk dikekalkan
Enjin Templat
Atur cara yang menggabungkan data dan templat untuk mengeluarkan hasil akhir dengan menganalisis templat dipanggil enjin templat Terdapat banyak jenis templat, dan terdapat banyak enjin templat yang sepadan. Templat yang lebih lama dipanggil ERB, yang digunakan dalam banyak rangka kerja web, seperti ASP.NET, Rails... Contoh di atas ialah contoh ERB. Terdapat dua konsep teras dalam ERB: menilai dan interpolasi. Di permukaan, nilai merujuk kepada bahagian yang terkandung dalam <% %>, dan interpolate merujuk kepada bahagian yang terkandung dalam <%= %>. Dari perspektif enjin templat, bahagian dalam penilaian tidak akan dikeluarkan secara langsung kepada hasil dan biasanya digunakan untuk kawalan proses manakala bahagian dalam interpolate akan dikeluarkan terus kepada hasil.
Dari perspektif pelaksanaan enjin templat, ia perlu bergantung pada kompilasi dinamik atau ciri tafsiran dinamik bahasa pengaturcaraan untuk memudahkan pelaksanaan dan meningkatkan prestasi. Contohnya: ASP.NET menggunakan kompilasi dinamik .NET untuk menyusun templat ke dalam kelas dinamik dan menggunakan refleksi untuk melaksanakan kod secara dinamik dalam kelas. Pelaksanaan ini sebenarnya lebih rumit kerana C# ialah bahasa pengaturcaraan statik, tetapi menggunakan JavaScript anda boleh menggunakan Function untuk melaksanakan enjin templat mudah dengan kod yang sangat sedikit. Artikel ini akan melaksanakan enjin templat ERB ringkas untuk menunjukkan kuasa JavaScript.
Penukaran teks templat
Untuk contoh di atas, semak perbezaan antara menggunakan templat dan tidak menggunakan templat:
Penulisan templat:
<ul> <% for(var i in items){ %> <li class='<%= items[i].status %>'><%= items[i].text %></li> <% } %> </ul>
Penulisan bukan templat:
var temp = '<ul>'; for(var i in items){ temp += "<li class='" + items[i].status + "'>" + items[i].text + "</li>"; } temp += '</ul>';
Melihat dengan teliti, kedua-dua kaedah itu sebenarnya sangat "serupa" dan boleh didapati dalam erti kata tertentu dalam perhubungan satu dengan satu. Jika teks templat boleh diubah menjadi kod untuk pelaksanaan, maka penukaran templat boleh dicapai. Terdapat dua prinsip dalam proses penukaran:
Apabila menemui teks biasa, ia disatukan terus menjadi rentetan
Apabila menghadapi interpolasi (iaitu <%= %>), kandungan dianggap sebagai pembolehubah dan disambung ke dalam rentetan
Apabila menghadapi penilaian (iaitu <% %>), ia dianggap secara langsung sebagai kod
Ubah contoh di atas mengikut prinsip di atas dan tambahkan fungsi umum:
var template = function(items){ var temp = ''; //开始变换 temp += '<ul>'; for(var i in items){ temp += "<li class='" + items[i].status + "'>" + items[i].text + "</li>"; } temp += '</ul>'; }
Akhir sekali laksanakan fungsi ini dan masukkan parameter data:
var result = template(items);
fungsi dinamik javascript
Ia boleh dilihat bahawa logik penukaran di atas sebenarnya sangat mudah, tetapi masalah utama ialah templat berubah, yang bermaksud bahawa kod program yang dihasilkan juga mesti dijana dan dilaksanakan pada masa jalan. Nasib baik, JavaScript mempunyai banyak ciri dinamik, salah satunya ialah Fungsi. Kami biasanya menggunakan kata kunci fungsi untuk mengisytiharkan fungsi dalam js, dan Fungsi jarang digunakan. Dalam js, fungsi ialah sintaks literal Masa jalan js akan menukar fungsi literal menjadi objek Fungsi, jadi Fungsi sebenarnya menyediakan mekanisme yang lebih rendah dan fleksibel.
Sintaks untuk mencipta fungsi secara langsung menggunakan kelas Fungsi adalah seperti berikut:
var function_name = new Function(arg1, arg2, ..., argN, function_body)
Contohnya:
//创建动态函数 var sayHi = new Function("sName", "sMessage", "alert(\"Hello \" + sName + sMessage);"); //执行 sayHi('Hello','World');
Kedua-dua badan fungsi dan parameter boleh dibuat melalui rentetan! sangat keren! Dengan ciri ini, teks templat boleh ditukar menjadi rentetan badan fungsi, supaya fungsi dinamik boleh dibuat dan dipanggil secara dinamik.
Idea pelaksanaan
Mula-mula gunakan ungkapan biasa untuk menerangkan interpolasi dan menilai, dan kurungan digunakan untuk menangkap kumpulan:
var interpolate_reg = /<%=([\s\S]+?)%>/g; var evaluate_reg = /<%([\s\S]+?)%>/g;
Untuk memadankan keseluruhan templat secara berterusan, kedua-dua ungkapan biasa ini digabungkan bersama, tetapi ambil perhatian bahawa semua rentetan yang boleh memadankan interpolasi boleh memadankan penilaian, jadi interpolasi perlu mempunyai keutamaan yang lebih tinggi:
var matcher = /<%=([\s\S]+?)%>|<%([\s\S]+?)%>/g
Reka bentuk fungsi untuk menukar templat, parameter input ialah rentetan teks templat dan objek data
var matcher = /<%=([\s\S]+?)%>|<%([\s\S]+?)%>/g //text: 传入的模板文本字串 //data: 数据对象 var template = function(text,data){ ... }
使用replace方法,进行正则的匹配和“替换”,实际上我们的目的不是要替换interpolate或evaluate,而是在匹配的过程中构建出“方法体”:
var matcher = /<%=([\s\S]+?)%>|<%([\s\S]+?)%>/g //text: 传入的模板文本字串 //data: 数据对象 var template = function(text,data){ var index = 0;//记录当前扫描到哪里了 var function_body = "var temp = '';"; function_body += "temp += '"; text.replace(matcher,function(match,interpolate,evaluate,offset){ //找到第一个匹配后,将前面部分作为普通字符串拼接的表达式 function_body += text.slice(index,offset); //如果是<% ... %>直接作为代码片段,evaluate就是捕获的分组 if(evaluate){ function_body += "';" + evaluate + "temp += '"; } //如果是<%= ... %>拼接字符串,interpolate就是捕获的分组 if(interpolate){ function_body += "' + " + interpolate + " + '"; } //递增index,跳过evaluate或者interpolate index = offset + match.length; //这里的return没有什么意义,因为关键不是替换text,而是构建function_body return match; }); //最后的代码应该是返回temp function_body += "';return temp;"; }
至此,function_body虽然是个字符串,但里面的内容实际上是一段函数代码,可以用这个变量来动态创建一个函数对象,并通过data参数调用:
var render = new Function('obj', function_body); return render(data);
这样render就是一个方法,可以调用,方法内部的代码由模板的内容构造,但是大致的框架应该是这样的:
function render(obj){ var temp = ''; temp += ... ... return temp; }
注意到,方法的形参是obj,所以模板内部引用的变量应该是obj:
<script id='template' type='javascript/template'> <ul> <% for(var i in obj){ %> <li class="<%= obj[i].status %>"><%= obj[i].text %></li> <% } %> </ul> </script>
看似到这里就OK了,但是有个必须解决的问题。模板文本中可能包含\r \n \u2028 \u2029等字符,这些字符如果出现在代码中,会出错,比如下面的代码是错误的:
temp += ' <ul> ' + ... ;
我们希望看到的应该是这样的代码:
temp += '\n \t\t<ul>\n' + ...;
这样需要把\n前面的转义成\即可,最终变成字面的\\n。
另外,还有一个问题是,上面的代码无法将最后一个evaluate或者interpolate后面的部分拼接进来,解决这个问题的办法也很简单,只需要在正则式中添加一个行尾的匹配即可:
var matcher = /<%=([\s\S]+?)%>|<%([\s\S]+?)%>|$/g;
相对完整的代码
var matcher = /<%=([\s\S]+?)%>|<%([\s\S]+?)%>|$/g //模板文本中的特殊字符转义处理 var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g; var escapes = { "'": "'", '\\': '\\', '\r': 'r', '\n': 'n', '\t': 't', '\u2028': 'u2028', '\u2029': 'u2029' }; //text: 传入的模板文本字串 //data: 数据对象 var template = function(text,data){ var index = 0;//记录当前扫描到哪里了 var function_body = "var temp = '';"; function_body += "temp += '"; text.replace(matcher,function(match,interpolate,evaluate,offset){ //找到第一个匹配后,将前面部分作为普通字符串拼接的表达式 //添加了处理转义字符 function_body += text.slice(index,offset) .replace(escaper, function(match) { return '\\' + escapes[match]; }); //如果是<% ... %>直接作为代码片段,evaluate就是捕获的分组 if(evaluate){ function_body += "';" + evaluate + "temp += '"; } //如果是<%= ... %>拼接字符串,interpolate就是捕获的分组 if(interpolate){ function_body += "' + " + interpolate + " + '"; } //递增index,跳过evaluate或者interpolate index = offset + match.length; //这里的return没有什么意义,因为关键不是替换text,而是构建function_body return match; }); //最后的代码应该是返回temp function_body += "';return temp;"; var render = new Function('obj', function_body); return render(data); }
调用代码可以是这样:
<script id='template' type='javascript/template'> <ul> <% for(var i in obj){ %> <li class="<%= obj[i].status %>"><%= obj[i].text %></li> <% } %> </ul> </script> ... var text = document.getElementById('template').innerHTML; var items = [ { text: 'text1' ,status:'done' }, { text: 'text2' ,status:'pending' }, { text: 'text3' ,status:'pending' }, { text: 'text4' ,status:'processing' } ]; console.log(template(text,items));
可见,我们只用了很少的代码就实现了一个简易的模板。
遗留的问题
还有几个细节的问题需要注意:
- 因为<%或者%>都是模板的边界字符,如果模板需要输出<%或者%>,那么需要设计转义的办法
- 如果数据对象中包含有null,显然不希望最后输出'null',所以需要在function_body的代码中考虑null的情况
- 在模板中每次使用obj的形参引用数据,可能不太方便,可以在function_body添加with(obj||{}){...},这样模板中可以直接使用obj的属性
- 可以设计将render返回出去,而不是返回转化的结果,这样外部可以缓存生成的函数,以提高性能

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas

Cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem pengecaman pertuturan dalam talian Pengenalan: Dengan perkembangan teknologi yang berterusan, teknologi pengecaman pertuturan telah menjadi bahagian penting dalam bidang kecerdasan buatan. Sistem pengecaman pertuturan dalam talian berdasarkan WebSocket dan JavaScript mempunyai ciri kependaman rendah, masa nyata dan platform merentas, dan telah menjadi penyelesaian yang digunakan secara meluas. Artikel ini akan memperkenalkan cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem pengecaman pertuturan dalam talian.

WebSocket dan JavaScript: Teknologi utama untuk merealisasikan sistem pemantauan masa nyata Pengenalan: Dengan perkembangan pesat teknologi Internet, sistem pemantauan masa nyata telah digunakan secara meluas dalam pelbagai bidang. Salah satu teknologi utama untuk mencapai pemantauan masa nyata ialah gabungan WebSocket dan JavaScript. Artikel ini akan memperkenalkan aplikasi WebSocket dan JavaScript dalam sistem pemantauan masa nyata, memberikan contoh kod dan menerangkan prinsip pelaksanaannya secara terperinci. 1. Teknologi WebSocket

Pengenalan kepada cara menggunakan JavaScript dan WebSocket untuk melaksanakan sistem pesanan dalam talian masa nyata: Dengan populariti Internet dan kemajuan teknologi, semakin banyak restoran telah mula menyediakan perkhidmatan pesanan dalam talian. Untuk melaksanakan sistem pesanan dalam talian masa nyata, kami boleh menggunakan teknologi JavaScript dan WebSocket. WebSocket ialah protokol komunikasi dupleks penuh berdasarkan protokol TCP, yang boleh merealisasikan komunikasi dua hala masa nyata antara pelanggan dan pelayan. Dalam sistem pesanan dalam talian masa nyata, apabila pengguna memilih hidangan dan membuat pesanan

JavaScript dan WebSocket: Membina sistem ramalan cuaca masa nyata yang cekap Pengenalan: Hari ini, ketepatan ramalan cuaca sangat penting kepada kehidupan harian dan membuat keputusan. Apabila teknologi berkembang, kami boleh menyediakan ramalan cuaca yang lebih tepat dan boleh dipercayai dengan mendapatkan data cuaca dalam masa nyata. Dalam artikel ini, kita akan mempelajari cara menggunakan teknologi JavaScript dan WebSocket untuk membina sistem ramalan cuaca masa nyata yang cekap. Artikel ini akan menunjukkan proses pelaksanaan melalui contoh kod tertentu. Kami

Tutorial JavaScript: Bagaimana untuk mendapatkan kod status HTTP, contoh kod khusus diperlukan: Dalam pembangunan web, interaksi data dengan pelayan sering terlibat. Apabila berkomunikasi dengan pelayan, kami selalunya perlu mendapatkan kod status HTTP yang dikembalikan untuk menentukan sama ada operasi itu berjaya dan melaksanakan pemprosesan yang sepadan berdasarkan kod status yang berbeza. Artikel ini akan mengajar anda cara menggunakan JavaScript untuk mendapatkan kod status HTTP dan menyediakan beberapa contoh kod praktikal. Menggunakan XMLHttpRequest

Berkenaan PPT masking, pasti ramai yang tidak faham dengannya ketika membuat PPT, tetapi hanya mengada-ngada untuk membuat apa yang mereka suka Oleh itu, ramai yang tidak tahu apa itu PPT masking, dan mereka juga tidak faham Saya tahu apa yang dilakukan oleh topeng ini, dan saya tidak tahu bahawa ia boleh menjadikan gambar itu kurang membosankan. Jadi, bagaimana untuk menambah topeng PPT? Sila baca di bawah. 1. Mula-mula kita buka PPT, pilih gambar kosong, kemudian klik kanan [Set Background Format] dan pilih warna pepejal. 2. Klik [Insert], word art, masukkan perkataan 3. Klik [Insert], klik [Shape]

Pengkhususan templat C++ mempengaruhi lebihan beban dan penulisan semula fungsi: Kelebihan beban fungsi: Versi khusus boleh menyediakan pelaksanaan berbeza bagi jenis tertentu, sekali gus menjejaskan fungsi yang dipilih pengkompil untuk memanggil. Mengatasi fungsi: Versi khusus dalam kelas terbitan akan mengatasi fungsi templat dalam kelas asas, menjejaskan kelakuan objek kelas terbitan apabila memanggil fungsi.

Pengenalan kepada kaedah mendapatkan kod status HTTP dalam JavaScript: Dalam pembangunan bahagian hadapan, kita selalunya perlu berurusan dengan interaksi dengan antara muka bahagian belakang, dan kod status HTTP adalah bahagian yang sangat penting daripadanya. Memahami dan mendapatkan kod status HTTP membantu kami mengendalikan data yang dikembalikan oleh antara muka dengan lebih baik. Artikel ini akan memperkenalkan cara menggunakan JavaScript untuk mendapatkan kod status HTTP dan memberikan contoh kod khusus. 1. Apakah kod status HTTP bermakna kod status HTTP apabila penyemak imbas memulakan permintaan kepada pelayan, perkhidmatan tersebut
