-2

我正在创建一个模板系统,该系统可以在客户端使用 Javascript 进行解释,以构建空白表单,例如给客户的一封信等。

我已经构建了模板并在伪代码中设置了逻辑,但是我对 jQuery 的不熟悉我可以使用一些方向来让我开始。

基本思想是在我的文本节点中有一个标记,它表示一个字段,例如 ${prologue},然后将其添加到一个名为“fields”的数组中,然后该数组将用于在 xml 中搜索相应的节点名称。

XML

    <?xml version="1.0" encoding="UTF-8"?>
<message>

    <text>${Prologue} - Dear ${Title} ${Surname}. This is a message from FUBAR. An engineer called but was unable to gain access, a new appointment has been made for ${ProductName} with order number ${VOLNumber}, on ${AppointmentDate} between ${AppointmentSlot}.
Please ensure you are available at your premises for the engineer. If this is not convenient, go to fubar.com or call 124125121515 before 12:00 noon the day before your appointment. Please refer to your order confirmation for details on what will happen on the day. ${Epilogue} - Free text field for advisor input<
</text>

    <inputTypes>
        <textBox type="text" fixed="n" size="100" alt="Enter a value">
            <Prologue size="200" value="BT ENG Appt Reschedule 254159" alt="Prologue field"></Prologue>
            <Surname value="Hoskins"></Surname>
            <ProductName value=""></ProductName>
            <VOLNumber size="8" value="" ></VOLNumber>
            <Epilogue value=""></Epilogue>  
        </textBox>
        <date type="datePicker" fixed="n" size="8" alt="Select a suitable appointment date">
            <AppointmentDate></AppointmentDate>
        </date>
        <select type="select" >
            <Title alt="Select the customers title">
                <values>
                    <Mr selected="true">Mr</Mr>
                    <Miss>Miss</Miss>
                    <Mrs>Mrs</Mrs>
                    <Dr>Dr</Dr>
                    <Sir>Sir</Sir>                  
                </values>
            </Title>
            <AppointmentSlot alt="Select the appointment slot">
                <values>
                    <Morning>9:30am - 12:00pm</Morning>
                    <Afternoon>1:00pm - 5:00pm</Afternoon>
                    <Evening>6:00pm - 9:00pm</Evening>
                </values>
            </AppointmentSlot>
        </select>
    </inputTypes>
</message>

伪代码

Get list of tags from text node and build array called "fields"
For each item in "fields" array:
Find node in xml that equals array item's name
Get attributes of that node
Jump to parent node
Get attributes of parent node
If attributes of parent node != child node then ignore
Else add the parent attributes to the result
Build html for field using all the data gathered from above

附录

这个逻辑可以吗,是否可以从节点的父节点开始向下导航?

同样关于继承,我们可以获得父属性,如果子属性不同,那么将它们添加到结果中?如果父项中的属性数量不等于子项中的数量怎么办?

请不要提供完全编码的解决方案,只是一些让我开始的预告片。

这是我到目前为止从文本节点中提取标签的内容

//get value of node "text" in xml
    var start = $(xml).find("text").text().indexOf('$');
    var end = $(xml).find("text").text().indexOf('}');
    var tag = "";
    var inputType;

    // find all tags and add them to a tag array
    while (start >= 0)
    {
        //console.log("Reach In Loop " + start)
        tag = theLetter.slice(start + 2, end);
        tagArray.push(tag);
        tagReplaceArray.push(theLetter.slice(start, end + 1));
        start = theLetter.indexOf('$', start + 1);
        end = theLetter.indexOf('}', end + 1);
    }

欢迎任何其他建议或类似问题的链接。

谢谢!

4

3 回答 3

5

我正在使用类似的技术来做 html 模板。

我发现使用字符串然后将其转换为 html 更容易,而不是使用元素。在您使用 jQuery 的情况下,您可以执行类似的操作:

将您的 xml 作为字符串:

var xmlString='<?xml version="1.0" encoding="UTF-8"?><message><text>${Prologue} - Dear ${Title} ${Surname}... ';

遍历字符串以使用正则表达式进行替换($1 是捕获的占位符,例如姓氏):

xmlString.replace(/$\{([^}]+)}/g,function($0,$1)...}

如果需要,转换为节点:

var xml=$(xmlString);

正则表达式的好处:

  • 更快(只是一个字符串,你不是在走 DOM)
  • 全局替换(例如,如果姓氏出现多次),只需循环一次对象属性
  • 简单的正则表达式 /${([^}]+)}/ 定位占位符
于 2013-02-06T21:50:55.837 回答
1

这只是一个让你前进的框架,就像你问的那样。

第一个概念是使用正则表达式来查找 ${ } 的所有匹配项。它返回一个类似 ["${one}","${tw 0 }","${ three}"] 的数组。

第二个概念是 htmlGenerator json 对象映射“inputTypes-->childname”到负责 html 打印输出的函数。

第三是不要忘记自然的javascript。.localname会给你xml元素的名字,并且node.attributes 应该给你一个namedNodeMap(记住不要对jquery对象执行自然的javascript,确保你引用的是为你找到的节点元素jQuery)。

实际流程很简单。

找到所有的 '${}' 标记并将结果存储在一个数组中。

在 xml 文档中找到所有标记并使用它们的父信息,将 html 存储在{"${one}":"<input type='text' .../>","${two}":"<select><option value='hello'>world!</option></select>" ...}

遍历地图并将源文本中的每个标记替换为您想要的 html。

javascript

    var $xmlDoc = $(xml); //store the xml document
    var tokenSource =$xmlDoc.find("message text").text(); 
    var tokenizer=/${[^}]+/g; //used to find replacement locations
    var htmlGenerators = {
      "textBox":function(name,$elementParent){
    //default javascript .attributes returns a namedNodeMap, I think jquery can handle it, otherwise parse the .attributes return into an array or json obj first.
      var parentAttributes = ($elementParent[0] && $elementParent.attributes)?$elementParent.attributes:null;
    //this may be not enough null check work, but you get the idea
      var specificAttributes =$elementParent.find(name)[0].attributes;
      var combinedAttributes = {};
      if(parentAttributes && specificAttributes){
    //extend or overwrite the contents of the first obj with contents from 2nd, then 3rd, ... then nth [$.extend()](http://api.jquery.com/jQuery.extend/)
          $.extend(combinedAttributes,parentAttributes,specificAttributes);
      }
      return $("<input>",combinedAttributes);
    },
      "date":function(name,$elementParent){
       //whatever you want to do for a 'date' text input
    },
      "select":function(name,$elementParent){
      //put in a default select box implementation, obviously you'll need to copy options attributes too in addition to their value / visible value.
    }
    };
    var html={};
    var tokens = tokenSource.match(tokenizer); //pull out each ${elementKey}
    for(index in tokens){
      var elementKey = tokens[index].replace("${","").replace("}"),"");//chomp${,}
      var $elementParent = $xmlDoc.find(elementKey).parent();//we need parent attributes.  javascript .localname should have the element name of your xml node, in this case "textBox","date" or "select".  might need a [0].localname....
      var elementFunction = ($elementParent.localname)?htmlGenerators[elementParent.localname]:null; //lookup the html generator function
      if(elementFunction != null){ //make sure we found one
        html[tokens[index]] = elementFunction(elementKey,elementParent);//store the result
      }
    }
  

      for(index in html){
       //for every html result, replace it's token
          tokenSource = tokenSource.replace(index,html[index]);
        }
于 2013-02-06T21:29:14.637 回答
1

从文本节点获取标签列表并构建名为“fields”的数组

要创建数组,我宁愿使用正则表达式,这是它的最佳用途之一(在我看来),因为我们确实在寻找一种模式:

var reg = /\$\{(\w+)\}/gm;
var i = 0;
var fields = new Array();

while (  (m = reg.exec(txt)) !== null)
{
    fields[i++] = m[1];
}

对于“字段”数组中的每个项目

jQuery 提供了一些实用功能

要遍历您的字段,您可以这样做:$.each(fields, function(index, value){});

浏览节点并检索值

就像你已经在做的那样使用jQuery 函数。

构建 HTML

我将为您负责的每种类型创建模板对象(在此示例中:TextSelect

然后使用所述模板,您可以用模板的 HTML 替换标记。

显示 HTML

最后一步是解析结果字符串并将其附加到正确的位置:

var ResultForm = $.parseHTML(txt); 

$("#DisplayDiv").append(ResultForm);

结论

就像你问的那样,我没有准备任何开箱即用的东西,我希望它能帮助你准备自己的答案。(然后我希望你能与社区分享)

于 2013-02-07T03:16:31.573 回答