微信号:we21cto

介绍:21CTO(21CTO.com)是中国项级技术专家的学习与服务平台.我们为CTO、技术总监、架构师等技术专家提供高质量的资讯、问答、活动等产品,同时与企业连接,提供技术咨询、研发、运维、技术支持、培训及人才招聘等服...

一个简洁的客户端模板语言

2018-04-08 23:03 21CTO

21CTO社区导读:一个开发者探讨了一种将某些JSON数据绑定到DOM元素的简单方法。



在最近的一个项目里,我想用一个简便方法将JSON数据绑定在DOM元素上,而无需引入任何库。我觉得已经想了一个非常整洁的解决方案,并满足了我对项目的全部需求。


这个解决方案用来对模板中DOM数据属性为data-bin-*的元素进行指令编码,这些属性可以在数据集属性的DOM元素中被访问,并且会自动对属性进行驼峰式处理(如设置innerText,比如一个属性名data-bin_inner-text-下划线字符)。


以下是该项目的示范模板:


<template id="itemTemplate">

  <div class="item new" data-bind_id="guid" id="">

    <h3><span data-bind_inner-text="title"></span></h3>

    <p class="description" data-bind_inner-text="content:encoded|description"></p>

    <div>

      <a data-bind_href="link" data-bind_inner-text="pubDate" data-bind_title="title" href="" title=""></a>

      <svg class="share" url="" title="" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" width="24" height="24">

        <path fill="none" d="M0 0h24v24H0z"></path><path d="M18 16c-.8 0-1.4.4-2 .8l-7-4v-1.5l7-4c.5.4 1.2.7 2 .7 1.7 0 3-1.3 3-3s-1.3-3-3-3-3 1.3-3 3v.7l-7 4C7.5 9.4 6.8 9 6 9c-1.7 0-3 1.3-3 3s1.3 3 3 3c.8 0 1.5-.3 2-.8l7.2 4.2v.6c0 1.6 1.2 3 2.8 3 1.6 0 3-1.4 3-3s-1.4-3-3-3z"></path>

      </svg>

    </div>

  </div>

</template>


正像你所看到的,我们使用了<template>元素来把HTML包起来,并保持其原样。这其中的内容可以有模板标签,也可以是DOM元素的任何内容。


为了把上面的DOM映射到所有实时数据的元素。


我用了以下一些基本算法:


1、克隆元素并将数据绑定。

2、遍历每个元素:

1)检查表单是否具有data-bind_的属性

2)获取键值,查找由“|”分隔的数据

3)将输入数据中第一个找到的键值直接映射到由data-bind_定义的节点属性

并返回新节点。


这个代码非常简单,如下:


const applyTemplate = (templateElement, data) => {

  const element = templateElement.content.cloneNode(true);    

  const treeWalker = document.createTreeWalker(element, NodeFilter.SHOW_ELEMENT, () => NodeFilter.FILTER_ACCEPT);

  while(treeWalker.nextNode()) {

    const node = treeWalker.currentNode;

    for(let bindAttr in node.dataset) {

      let isBindableAttr = (bindAttr.indexOf('bind_') == 0) ? true : false;

      if(isBindableAttr) {

        let dataKeyString = node.dataset[bindAttr];

        let dataKeys = dataKeyString.split("|");

        let bindKey = bindAttr.substr(5);

        for(let dataKey of dataKeys) {

          if(dataKey in data && data[dataKey] !== "") {

            node[bindKey] = data[dataKey];

            break;

          }

        }

      }

    }

  }

  return element;

}


我其实并不希望任何人使用它,我想展示如何为简单任务构建数据绑定工具,而不必使用完整的库或框架。



作者:Paul Kinlan

译者:js小蓝

来源:https://dzone.com/articles/a-simple-client-side-templating-language


 
21CTO 更多文章 TIOBE 4 月排行榜:SQL 进入前十,Python 继续攀升 首都程序员最不爱运动、成都程序员有房又有车、上海程序员最辛苦……原来我们是这样的程序员! 你是现代软件开发者吗? 从开发者到卓有成效领导者之最佳实践 基于大数据搭建社交好友推荐系统
猜您喜欢 他拒绝年入百万的工资,只为帮你多赚10万一年 Java程序员也应该知道的系统知识系列之虚拟化 大数据告诉你,什么样的家庭能培养出高考“状元” 大型网站的灵魂——性能