Как предотвратить дублирование кода при реализации прогрессивного улучшения?

Я запускаю веб-приложение PHP, которое позволяет пользователям просматривать списки элементов.

Простой сайт использует PHP для написания HTML для отображения результатов поиска:

<body>
   <?php
      foreach($results as $item) {
         echo "<div class='item'>".
                 "<img src='images/items/".$item['imageName'].".png' />".
                 "<span class='itemDescription'>".$item['text']."</span>".
              "</div>";
      }
    ?>
 </body>

Однако, когда Javascript включен, я использую AJAX для отображения результатов:

function fireSearch(query) {
   $.post("ajax/search.php", {q: query}, function(items) {
      for (var i in items) {
         $("body").append(
             "<div class='item'>"+
                "<img src='images/items/"+items[i]['imageName']+".png' />"+
                "<span class='itemDescription'>"+items[i]['text']+"</span>"+
             "</div>";
      }
   }
}

Я мог бы просто написать функцию PHP с именем get_item_html($item) и заставить запрос AJAX возвращать чистый HTML и просто помещать его в DOM, но если запрос возвращает много результатов, это было бы настоящей тратой полосы пропускания, когда все, что мне действительно нужно для создания HTML — это imageName и text.

Это просто то, с чем я должен справиться, или есть какое-то элегантное решение?

И есть ли у этой проблемы название, чтобы я мог его погуглить?


person Dori    schedule 18.02.2013    source источник
comment
Это называется шаблонизация. Некоторые форматы шаблонов можно использовать как на стороне сервера, так и на стороне клиента.   -  person Bergi    schedule 18.02.2013


Ответы (3)


Хорошо понял.

Лучшее решение, которое я нашел, — использовать Mustache, написать несколько шаблонов и прочитать шаблоны как на Javascript, так и на PHP.

Библиотека Mustache предоставляет PHP и Javascript, так что не беспокойтесь:

  1. Создайте несколько .mustache шаблонов
  2. В PHP используйте классы и методы, предоставляемые библиотекой, для создания HTML и echo его
  3. В Javascript используйте шаблон, добавив сценарий mustache.js, и для каждого шаблона, используемого страницей, добавьте тег сценария с содержимым файла шаблона echoed в:
    <script id="arbitraryID" type="text/mustache">
    <?php echo file_get_contents(__DIR__."/templates/myTmpl.mustache"); ?>
    </script>< br/> Затем шаблон доступен, выполнив (стиль jQuery):
    var tmpl = $("#arbitraryID").html();

Надеюсь, это поможет любому, кто найдет этот вопрос открытым...

person Dori    schedule 19.02.2013

Я бы позволил функции ajax вернуть сборку json, а затем я бы превратил ваш .append() в настраиваемую минимизированную функцию, чтобы уменьшить размер, и в результате у вас будет более чистый код.

person Hultin    schedule 18.02.2013
comment
Как это решает проблему? У меня по-прежнему будут функция PHP и функция Javascript, делающие одно и то же. - person Dori; 18.02.2013
comment
К сожалению, я неправильно прочитал ветку, и нет, мой ответ совсем не поможет. ~обвиняет, что не пил кофе, когда писал ответ~ - person Hultin; 18.02.2013

Как упоминал Берги, используйте шаблон для инкапсуляции отображения информации и отправляйте только имя изображения и текст в запросах ajax.

Есть много способов реализовать шаблонизацию (много хорошего слышал о handlebars.js, еще не пробовал), самый простой — написать html-разметку с данными, полученными по ajax-запросу, и добавить ее в контейнер. , возможно, используя простую функцию, которую вы позже сможете заменить правильным подходом к шаблонам.

function drawItem(item) {
    return "<div class='item'>" +
             "<img src='images/items/"+item.imageName+"' />" +
             "<span class='itemDescription'>"+item.text+"</span>" +
           "</div>";
}

function fireSearch(query) {
    $.post("ajax/search.php", {q: query}, function(items) {
        for (var i=0; i<items.length; i++) {
            $("body").append(drawItem(items[i]);
        }
    }, 'json');
}

ajax/search.php вернет что-то вроде: [{"imageName":"blabla.png","text":"moomoo"},...]

Генерируется файлом search.php следующим образом:

<?php 
echo json_encode(array(
    array("imageName"=>"blabla.png", "text"=>"moomoo"),
    array("imageName"=>"example2.png", "text"=>"second example")
));

?>
person cernunnos    schedule 18.02.2013
comment
Спасибо, но я до сих пор не могу понять из вашего ответа, как мне не нужно будет копировать код между сценариями PHP и сценариями Javascript. - person Dori; 18.02.2013
comment
Вы не копируете код, в этом случае Javascript используется для отправки запроса AJAX на сервер, который должен вернуть данные в кодировке JSON. Используйте echo json_encode(yourarray) в php-скрипте. Я отредактирую пост фрагментом php. - person cernunnos; 18.02.2013
comment
Но для прогрессивного улучшения мне нужно, чтобы PHP знал, как создавать HTML. Недостаточно знать, как создать строку JSON, совместимую с клиентским скриптом. - person Dori; 19.02.2013
comment
Я понимаю. Единственное элегантное решение, которое я вижу, это Mustache (mustache.github.com), но это еще одна библиотека, которую вы добавляете в ваше приложение. Если вы действительно хотите уменьшить пропускную способность, вы можете отправить шаблон элемента результатов поиска с результатами JSON, таким образом, только PHP должен знать, как рисовать элемент поиска. Я не уверен, что улучшение пропускной способности стоит сложности, которая будет зависеть от количества посетителей и имеющихся у вас ресурсов. - person cernunnos; 19.02.2013