2011-05-27 92 views
3

我已经问过关于如何避免在js中编写html的问题,然后有人告诉我使用javascript模板,例如,jquery/template pugin和ect。javascript模板和事件处理

这是当生成静态html,例如一个好主意:

<ul id="productList"></ul> 

<script id="productTemplate" type="text/x-jquery-tmpl"> 
    <li><a>${Name}</a> (${Price})</li> 
</script> 

<script type="text/javascript"> 
    var products = [ 
     { Name: "xxx", Price: "xxx" }, 
     { Name: "yyy", Price: "xxx" }, 
     { Name: "zzz", Price: "xxx" } 
    ]; 

    // Render the template with the products data and insert 
    // the rendered HTML under the "productList" element 
    $("#productTemplate").tmpl(products) 
     .appendTo("#productList"); 
</script> 

然而,当我尝试一些事件绑定生成的HTML,我遇到了一些问题。

例如,我有一个页面,用户可以通过价格/名称/位置搜索某些产品。

所以,我有三个功能:

searchByPrice(lowPrice,highPrice,productType,currentPage) 
searchByName(name,productType,currentPage); 
searchByLocation(location,currentpage); 

上述所有功能都在服务器端的realated方法,他们将retrun产品USINT的XML格式。因为它们会重新运行这么多项目,所以我必须分页,“currengPage”用于告诉服务器端应该返回哪部分结果。

当客户端从服务器端获得结果时,现在它是js将它们显示在div中,并且如果可能的话创建一​​个页面栏。

之前,我已经知道了模板,我用这种方式(这是我最讨厌的,尽我所能来避免):

function searchByPrice(lowPrice,highPrice,productType,currentPage){ 
    var url="WebService.asmx/searchByPrice?low="+lowPrice="&high="+highPrice+"&curPage="+currentPage; 
    //code to create the xmlHttp object 
    xmlhttp.open("GET",url,true); 
    xmlhttp.onreadystatechange=function(){ 
     if (xmlhttp.readyState==4 && xmlhttp.status==200){ 
      var i=0; 
      var Prohtml=""; 
      var proList=parseProductList(xmlhttp.responseText); 
      for(i=0;i<prolist.length;i++){ 
       Prohtml+="<li><a href='#'>"+prolist[i].name+"</a> ("+prolist[i].price"+)</li>"; 
      } 


      //generate the paging bar: 
      var totleResult=getTotleResultNumber(xmlhttp.responseText); 
      if(totleResult>10){ 
       var paghtml="<span>"; 
       //need the paging 
       var pagNum=totleResult/10+1; 
       for(i=1;i<=pagenum;i++){ 
        paghtml+="<a onclick='searchByPrice(lowPrice,highPrice,productType,currentPage+1)'>i</a>"; 
        //here the synax is not right,since I am really not good at handle the single or doule '"' in this manner. 

        //also if in the searchByName function,the click function here should be replaced using the searchByName(...) 


       } 

      } 
     } 
    } 

} 

在这个例子中,很容易使用模板来生成“Prohtml “由于没有事件处理,但”paghtml“如何,点击功能在不同的搜索类型中是不同的。

那么,有什么好主意来解决这个问题?

回答

3

或者:

创建DOM元素,而不是建立HTML字符串,使用document.createElement或小library,如果你”重新做这些,这将允许你以通常的方式立即附加事件。

给它需要利用事件处理程序的一个唯一的ID,并建立事件列表一旦HTML已插入到文档中要附加的每个元素。

E.g.:

var eventHandlers = [] 
    , eventCount = 0; 

for (i = 1; i <= pagenum; i++) { 
    var id = "search" + eventCount++; 
    html += "<a id='" + id + "'>" + i + "</a>"; 
    eventHandlers.push([id, 'click', 
         handler(searchByPrice, lowPrice, highPrice, productType, currentPage + i)]) 
} 

// Later... 
someElement.innerHTML = html; 
registerEvents(eventHandlers); 

其中registerEvents是:

function registerEvents(eventHandlers) { 
    for (var i = 0, l = eventHandlers.length; i < l; i++) { 
    var eventHandler = eventHandlers[i], 
     id = eventHandler[0], 
     eventName = eventHandler[1], 
     func = eventHandler[2]; 
    // Where addEvent is your cross-browser event registration function 
    // of choice... 
    addEvent(document.getElementById(id), eventName, func); 
    } 
} 

而且handler仅仅是一个快速的方法可以关上传递的所有参数:

/** 
* Creates a fnction which calls the given function with any additional 
* arguments passed in. 
*/ 
function handler(func) { 
    var args = Array.prototype.slice.call(arguments, 1); 
    return function() { 
    func.apply(this, args); 
    } 
} 

我用这样的方式(但在我的DOMBuilder数据库的HTML生成部分中自动添加唯一的ID,它为基因提供a convenience method根据您定义的内容对HTML进行评级,使用innerHTML将其插入给定元素并注册存在的任何事件处理程序。其定义内容的语法与输出模式无关,它允许您在大多数情况下无缝切换DOM和HTML输出。

3

首先,您可以简单地使用$.get()$.ajax()来进行AJAX调用。其次,可以使用.live().delegate()将事件绑定到不存在的元素。

第三,您可以使用锚元素中的数据属性作为传递事件处理函数参数的方法,请参阅.data()

所以,重写你的函数,你有没有可能像下面这样:

function searchByPrice(event) { 
    $this = $(this); 
    var lowPrice = $this.data('lowPrice'), 
     highPrice = $this.data('lowPrice'), 
     productType = $this.data('productType'), 
     currentPage = $this.data('currentPage'); 

    var url = "WebService.asmx/searchByPrice?low=" + lowPrice = "&high=" + highPrice + "&curPage=" + currentPage; 

    $.get(url, function(data, textStatus, jqXHR) { 
     var i = 0; 
     var Prohtml = ""; 
     var proList = parseProductList(data); 
     for (i = 0; i < prolist.length; i++) { 
      Prohtml += "<li><a href='#'>" + prolist[i].name + "</a> (" + prolist[i].price "+)</li>"; 
     } 

     //generate the paging bar: 
     var totleResult = getTotleResultNumber(data); 
     if (totleResult > 10) { 
      var paghtml = "<span>"; 

      //need the paging 
      var pagNum = totleResult/10 + 1; 
      for (i = 1; i <= pagenum; i++) { 
       paghtml += '<a class="pagelink" ' + 
        'data-lowPrice="' + lowPrice + '" ' + 
        'data-highPrice="' + highPrice + '" ' + 
        'data-productType="' + productType + '" ' + 
        'data-currentPage="' + (currentpage + 1) + '">' + i + '</a>'; 
       //here the synax is not right,since I am really not good at handle the single or doule '"' in this manner. 

       //also if in the searchByName function,the click function here should be replaced using the searchByName(...) 

      } 
     } 
    }); 
} 


$(document).ready(function(){ 
    $("a.pagelink").live('click', searchByPrice); 
});