2011-05-27 45 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); 
});