


Une brève analyse des méthodes de mise en œuvre de base du moteur de modèle JavaScript_Connaissances de base
Le modèle sépare les données et la présentation, ce qui facilite la maintenance de la logique et des effets de la présentation. À l’aide de l’objet Function de JavaScript, créez étape par étape un moteur de conversion de modèles extrêmement simple
Présentation du modèle
Le modèle fait généralement référence à du texte intégré à une sorte de code de langage de programmation dynamique. Les données et les modèles peuvent être combinés sous une certaine forme pour produire des résultats différents. Les modèles sont généralement utilisés pour définir le formulaire d'affichage, ce qui peut rendre la présentation des données plus riche et plus facile à maintenir. Par exemple, voici un exemple de modèle :
<ul> <% for(var i in items){ %> <li class='<%= items[i].status %>'><%= items[i].text %></li> <% } %> </ul>
S'il existe les données des éléments suivants :
items:[ { text: 'text1' ,status:'done' }, { text: 'text2' ,status:'pending' }, { text: 'text3' ,status:'pending' }, { text: 'text4' ,status:'processing' } ]
En le combinant d'une manière ou d'une autre, le code HTML suivant peut être généré :
<ul> <li class='done'>text1<li> <li class='pending'>text2<li> <li class='pending'>text3<li> <li class='processing'>text4<li> </ul>
Si vous souhaitez obtenir le même effet sans utiliser de modèle, c'est-à-dire afficher les données ci-dessus en conséquence, vous devez procéder comme suit :
var temp = '<ul>'; for(var i in items){ temp += "<li class='" + items[i].status + "'>" + items[i].text + "</li>"; } temp += '</ul>';
On peut constater que l'utilisation de modèles présente les avantages suivants :
Écriture HTML simplifiée
Ayez plus de contrôle sur la présentation des données grâce à des éléments de programmation (tels que des boucles et des branches conditionnelles)
Sépare les données et l'affichage, ce qui rend la logique d'affichage et les effets plus faciles à maintenir
Moteur de modèles
Un programme qui combine des données et des modèles pour générer le résultat final en analysant des modèles est appelé moteur de modèles. Il existe de nombreux types de modèles et de nombreux moteurs de modèles correspondants. Un modèle plus ancien s'appelle ERB, qui est utilisé dans de nombreux frameworks Web, tels que ASP.NET, Rails... L'exemple ci-dessus est un exemple d'ERB. Il existe deux concepts fondamentaux dans ERB : évaluer et interpoler. En apparence, évaluer fait référence à la partie contenue dans <% %> et interpoler fait référence à la partie contenue dans <%= %>. Du point de vue du moteur de modèle, la partie en évaluation ne sera pas directement sortie vers le résultat et est généralement utilisée pour le contrôle du processus tandis que la partie en interpolation sera directement sortie vers le résultat ;
Du point de vue de la mise en œuvre du moteur de modèles, il doit s'appuyer sur les fonctionnalités de compilation dynamique ou d'interprétation dynamique du langage de programmation pour simplifier la mise en œuvre et améliorer les performances. Par exemple : ASP.NET utilise la compilation dynamique de .NET pour compiler des modèles en classes dynamiques et utilise la réflexion pour exécuter dynamiquement le code dans la classe. Cette implémentation est en réalité plus compliquée car C# est un langage de programmation statique, mais en utilisant JavaScript, vous pouvez utiliser Function pour implémenter un moteur de modèle simple avec très peu de code. Cet article implémentera un moteur de modèle ERB simple pour montrer la puissance de JavaScript.
Conversion de texte de modèle
Pour l'exemple ci-dessus, examinez la différence entre utiliser et ne pas utiliser de modèles :
Rédaction du modèle :
<ul> <% for(var i in items){ %> <li class='<%= items[i].status %>'><%= items[i].text %></li> <% } %> </ul>
Écriture sans modèle :
var temp = '<ul>'; for(var i in items){ temp += "<li class='" + items[i].status + "'>" + items[i].text + "</li>"; } temp += '</ul>';
En y regardant bien, les deux méthodes sont en réalité très "similaires" et se retrouvent dans un certain sens de correspondance biunivoque. Si le texte du modèle peut être transformé en code à exécuter, la conversion du modèle peut alors être réalisée. Il y a deux principes dans le processus de conversion :
Lorsque vous rencontrez du texte ordinaire, il est directement concaténé en chaînes
Lors d'une interpolation (c'est-à-dire <%= %>), le contenu est traité comme une variable et épissé dans la chaîne
Lorsqu'il rencontre une évaluation (c'est-à-dire <% %>), il est directement traité comme du code
Transformez l'exemple ci-dessus selon les principes ci-dessus et ajoutez une fonction générale :
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>'; }
Enfin, exécutez cette fonction et transmettez les paramètres de données :
var result = template(items);
Fonction dynamique javascript
On peut voir que la logique de conversion ci-dessus est en fait très simple, mais le problème clé est que le modèle change, ce qui signifie que le code du programme généré doit également être généré et exécuté au moment de l'exécution. Heureusement, JavaScript possède de nombreuses fonctionnalités dynamiques, dont Function. Nous utilisons généralement le mot-clé function pour déclarer des fonctions dans js, et Function est rarement utilisé. En js, function est une syntaxe littérale. Le runtime de js convertira la fonction littérale en un objet Function, donc Function fournit en fait un mécanisme plus bas et plus flexible.
La syntaxe pour créer directement une fonction à l'aide de la classe Function est la suivante :
var function_name = new Function(arg1, arg2, ..., argN, function_body)
Par exemple :
//创建动态函数 var sayHi = new Function("sName", "sMessage", "alert(\"Hello \" + sName + sMessage);"); //执行 sayHi('Hello','World');
Le corps de la fonction et les paramètres peuvent être créés via des chaînes ! Tellement cool ! Grâce à cette fonctionnalité, le texte du modèle peut être converti en une chaîne de corps de fonction, afin que des fonctions dynamiques puissent être créées et appelées dynamiquement.
Idées de mise en œuvre
Utilisez d'abord des expressions régulières pour décrire l'interpolation et l'évaluation, et les parenthèses sont utilisées pour la capture de groupe :
var interpolate_reg = /<%=([\s\S]+?)%>/g; var evaluate_reg = /<%([\s\S]+?)%>/g;
Afin de faire correspondre en permanence l'ensemble du modèle, ces deux expressions régulières sont fusionnées, mais notez que toutes les chaînes qui peuvent correspondre à l'interpolation peuvent correspondre à l'évaluation, l'interpolation doit donc avoir une priorité plus élevée :
var matcher = /<%=([\s\S]+?)%>|<%([\s\S]+?)%>/g
Concevez une fonction de conversion de modèles, les paramètres d'entrée sont des chaînes de texte de modèle et des objets de données
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返回出去,而不是返回转化的结果,这样外部可以缓存生成的函数,以提高性能

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Sujets chauds



Comment utiliser WebSocket et JavaScript pour mettre en œuvre un système de reconnaissance vocale en ligne Introduction : Avec le développement continu de la technologie, la technologie de reconnaissance vocale est devenue une partie importante du domaine de l'intelligence artificielle. Le système de reconnaissance vocale en ligne basé sur WebSocket et JavaScript présente les caractéristiques d'une faible latence, d'un temps réel et d'une multiplateforme, et est devenu une solution largement utilisée. Cet article explique comment utiliser WebSocket et JavaScript pour implémenter un système de reconnaissance vocale en ligne.

WebSocket et JavaScript : technologies clés pour réaliser des systèmes de surveillance en temps réel Introduction : Avec le développement rapide de la technologie Internet, les systèmes de surveillance en temps réel ont été largement utilisés dans divers domaines. L'une des technologies clés pour réaliser une surveillance en temps réel est la combinaison de WebSocket et de JavaScript. Cet article présentera l'application de WebSocket et JavaScript dans les systèmes de surveillance en temps réel, donnera des exemples de code et expliquera leurs principes de mise en œuvre en détail. 1. Technologie WebSocket

Introduction à l'utilisation de JavaScript et de WebSocket pour mettre en œuvre un système de commande en ligne en temps réel : avec la popularité d'Internet et les progrès de la technologie, de plus en plus de restaurants ont commencé à proposer des services de commande en ligne. Afin de mettre en œuvre un système de commande en ligne en temps réel, nous pouvons utiliser les technologies JavaScript et WebSocket. WebSocket est un protocole de communication full-duplex basé sur le protocole TCP, qui peut réaliser une communication bidirectionnelle en temps réel entre le client et le serveur. Dans le système de commande en ligne en temps réel, lorsque l'utilisateur sélectionne des plats et passe une commande

JavaScript et WebSocket : Construire un système efficace de prévisions météorologiques en temps réel Introduction : Aujourd'hui, la précision des prévisions météorologiques revêt une grande importance pour la vie quotidienne et la prise de décision. À mesure que la technologie évolue, nous pouvons fournir des prévisions météorologiques plus précises et plus fiables en obtenant des données météorologiques en temps réel. Dans cet article, nous apprendrons comment utiliser la technologie JavaScript et WebSocket pour créer un système efficace de prévisions météorologiques en temps réel. Cet article démontrera le processus de mise en œuvre à travers des exemples de code spécifiques. Nous

Concernant le masquage PPT, beaucoup de gens ne doivent pas le connaître. La plupart des gens ne le comprennent pas complètement lorsqu'ils créent un PPT, mais l'inventent simplement pour créer ce qu'ils aiment. Par conséquent, beaucoup de gens ne savent pas ce que signifie le masquage PPT et ne le comprennent pas non plus. Je sais ce que fait ce masque, et je ne sais même pas s'il peut rendre l'image moins monotone. Amis qui veulent apprendre, venez apprendre et ajoutez des masques PPT à vos images PPT. Alors, comment ajouter un masque PPT ? S'il vous plaît lire ci-dessous. 1. Nous ouvrons d'abord PPT, sélectionnons une image vierge, puis cliquons avec le bouton droit sur [Définir le format d'arrière-plan] et sélectionnons une couleur unie. 2. Cliquez sur [Insérer], Word Art, entrez le mot 3. Cliquez sur [Insérer], cliquez sur [Forme]

Tutoriel JavaScript : Comment obtenir le code d'état HTTP, des exemples de code spécifiques sont requis Préface : Dans le développement Web, l'interaction des données avec le serveur est souvent impliquée. Lors de la communication avec le serveur, nous devons souvent obtenir le code d'état HTTP renvoyé pour déterminer si l'opération a réussi et effectuer le traitement correspondant en fonction de différents codes d'état. Cet article vous apprendra comment utiliser JavaScript pour obtenir des codes d'état HTTP et fournira quelques exemples de codes pratiques. Utilisation de XMLHttpRequest

Les spécialisations de modèles C++ affectent la surcharge et la réécriture des fonctions : Surcharge de fonctions : les versions spécialisées peuvent fournir différentes implémentations d'un type spécifique, affectant ainsi les fonctions que le compilateur choisit d'appeler. Remplacement de fonction : la version spécialisée dans la classe dérivée remplacera la fonction modèle dans la classe de base, affectant le comportement de l'objet de classe dérivée lors de l'appel de la fonction.

Introduction à la méthode d'obtention du code d'état HTTP en JavaScript : Dans le développement front-end, nous devons souvent gérer l'interaction avec l'interface back-end, et le code d'état HTTP en est une partie très importante. Comprendre et obtenir les codes d'état HTTP nous aide à mieux gérer les données renvoyées par l'interface. Cet article explique comment utiliser JavaScript pour obtenir des codes d'état HTTP et fournit des exemples de code spécifiques. 1. Qu'est-ce que le code d'état HTTP ? Le code d'état HTTP signifie que lorsque le navigateur lance une requête au serveur, le service
