шаблон JavaScript и обработка событий - PullRequest
3 голосов
/ 27 мая 2011

Я задал вопрос о том, как избежать записи html в js, затем некоторые люди говорят мне, используя шаблон 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);

ALl вышеупомянутая функция имеет реализованный метод на стороне сервера, и они будутперезапустите продукты с использованием формата 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", функция щелчка отличается в разных типах поиска.

Итак, есть ли хорошая идея, чтобы передать это?

Ответы [ 2 ]

3 голосов
/ 05 июня 2011

Или:

Создайте элементы DOM вместо построения HTML-строк, используя document.createElement или небольшую библиотеку , если вы делаете это много, что позволит вам немедленно прикреплять события обычным способом.

или

Дайте каждому элементу, который должен использовать обработчики событий, уникальный идентификатор и создайте список событий, которые нужно присоединить после вставки 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);
  }
}

Я использую что-то вроде этого подхода (но автоматически добавляя уникальные идентификаторы при необходимости) в части генерации HTML моей библиотеки DOMBuilder , которая предлагает удобный метод для генерации HTML из контента Вы определили, вставив его в заданный элемент с помощью innerHTML и зарегистрировав любые обработчики событий, которые присутствовали. Его синтаксис для определения содержимого не зависит от режима вывода, что позволяет в большинстве случаев без проблем переключаться между выводом DOM и HTML.

3 голосов
/ 05 июня 2011

Прежде всего, вы можете просто использовать $.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);
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...