【问题标题】:the javascript template and the event handlingjavascript 模板和事件处理
【发布时间】:2011-06-06 01:01:36
【问题描述】:

我问了一个关于如何避免在js中编写html的问题,然后有人告诉我使用javascript模板,例如jquery/template pugin等。

生成静态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);

上述所有函数在服务器端都有一个关联的方法,它们将使用xml格式重新运行产品。

由于他们会返回这么多的项目,所以我必须对它们进行分页,“currengPage”用于告诉服务器端应该返回哪部分结果。

当客户端从服务器端获取结果时,现在是 js 将它们显示在他的 div 中,并尽可能创建一个 Paging Bar。

在我知道模板之前,我就用这种方式(我最讨厌,尽量避免):

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”呢,不同搜索类型的点击功能不同。

那么,有什么好主意来处理这个吗?

【问题讨论】:

    标签: javascript templates pagination


    【解决方案1】:

    要么:

    创建 DOM 元素而不是构建 HTML 字符串,使用 document.createElement 或小的 library(如果您经常这样做),这将允许您以通常的方式立即附加事件。

    为需要使用事件处理程序的每个元素提供一个唯一 ID,并建立一个事件列表,以便在 HTML 插入文档后附加。

    例如:

    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 输出之间无缝切换。

    【讨论】:

      【解决方案2】:

      首先,您可以简单地使用$.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);
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-04-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-09
        相关资源
        最近更新 更多