Сколько кода должно быть в представлении CodeIgniter? - PullRequest
8 голосов
/ 15 января 2011

Первые шаги сделаны, некоторые страницы закодированы.И после просмотра результата у меня возник вопрос: сколько кода должно быть в шаблонах (просмотр)?

Например, вот файл шаблона:

<?php $this->load->view('header'); ?>
<?php $this->load->view('banner'); ?>   

<div id="items">
<?php
for($i=0; $i<count($main); $i++) {
    echo '<div class="item">
        <div class="name">'.$main[$i]['name'].'</div>';
    if($main[$i]['icq']=='') { }
        else { echo '<div class="phone">'.$main[$i]['phone'].'</div>'; }
    echo '</div>';
}
?>
</div>

<?php $this->load->view('footer'); ?>

Как вы думаете, в этом шаблоне слишком много кода или это нормально?

Ответы [ 7 ]

16 голосов
/ 15 января 2011

Первый ответ на самом деле был точным, но пользователь удалил его (вероятно, из-за давления со стороны сверстников). По сути, вам не нужна логика в вашем шаблоне . В идеальном мире у вас был тег для всех данных модели, но поскольку мы находимся в мире HTML, его нет, поэтому вам нужно либо использовать XSLT, либо использовать ViewHelpers.

Давайте сосредоточимся на подходе ViewHelper.

Это трудно поддерживать:

<div id="items">
<?php
for($i=0; $i<count($main); $i++) {
    echo '<div class="item">
        <div class="name">'.$main[$i]['name'].'</div>';
    if($main[$i]['icq']=='') { }
        else { echo '<div class="phone">'.$main[$i]['phone'].'</div>'; }
    echo '</div>';
}
?>
</div>

И лучше не будет, если вы замените PHP на Smarty. Это легко поддерживать:

<div id="items">
    <?php echo itemlist($items, 'template.htm') ?>;
</div>

Ниже теперь удаленного вопроса был комментатор, возражающий против этого "кода, который не легко поддерживать для не кодеров, потому что теперь они не знают, где определен itemlist и что он делает." но это полная чепуха. Подумай об этом на секунду.

С одной стороны, они утверждают, что у некодеров будут проблемы с простым вызовом функции, но с другой стороны они ожидают, что они поймут путаницу кода PHP, смешанного с HTML. Дизайнер заботится не о логике представления, а о фактической презентации. Выход.

Одиночный вызов функции ясно говорит: «здесь будет список элементов», который гораздо легче понять, чем «здесь есть for, который повторяет div и, возможно, что-то еще, если дан icq». Вызов функции так же хорош, как тег. Он имеет четко определенный вход и выход. Как он достигает такого результата, не имеет значения ни для кого, кроме разработчика.

Ваш ViewHelper инкапсулирует логику представления. Это фрагмент, который вы можете использовать во всех своих представлениях. Это гораздо более легко поддерживать, чем копировать и вставлять всю эту логику снова и снова, когда это необходимо. В приведенном выше примере у помощника есть два аргумента:

  • $ items - это массив или другой проходимый тип, содержащий ваши фактические данные элемента
  • 'template.htm' - это имя файла шаблона, используемого для визуализации данных

Я сделаю второй вариант необязательным, поскольку я предполагаю, что в любом случае это всегда один и тот же шаблон. Но поскольку комментатор жаловался, что некодер не будет знать, где искать, я счел необходимым показать, как легко сказать некодеру, где искать.

function itemlist($items, $template = './templates/itemlist.htm') {
    ob_start();
    foreach($items as $item) {
        include $template;
    }
    return ob_get_flush();
}

Могут быть более эффективные подходы для решения вопроса о включении шаблона. Основная идея должна быть ясной, хотя. Скрыть логику представления от фактического шаблона. Ваш "template.htm" будет выглядеть так:

<div class="item">
    <div class="name"><?php echo $item['name'] ?></div>
    <?php echo contact($item, 'icq' 'phone'); ?>
</div>

Нет, если и остальное. Нет конкатенации строк или фигурных скобок. Логика принятия решения о том, как связаться с пользователем, также скрыта в ViewHelper. Все, что некодер должен знать сейчас, это аргументы ViewHelpers, и это так же просто, как знать, какой атрибут записать в тег. При необходимости дайте им шпаргалку.

Информация, связанная с данной:


EDIT

Из-за двух комментариев ниже я решил расширить этот ответ. Выше не абстракция ради абстракции. Это для повторного использования и ремонтопригодности. Я уже говорил об этом выше, но позвольте мне объяснить это здесь снова.

На самом деле, я нахожу странным возражать против использования ViewHelpers, потому что у вас будет «представление в двух местах», но вы не будете жаловаться на разделение заголовка, баннера и колонтитула. Это то же самое. Вы изолируете части, которые можно использовать повторно, и поместите их в свои собственные шаблоны. Отделение логики от шаблона на этом шаге является просто естественным следующим шагом для достижения еще большей ремонтопригодности.

Шаблон представления, который содержит логику, фактически является сценарием, а не шаблоном. Любой шаблон представления, который содержит логику для сборки, обречен на повторение. Это может не быть проблемой для небольших сайтов, но если вы работаете на сайте с парой дюжин или даже сотен представлений и виджетов, не абстрагирование этих частей приведет к дублированию кода. Поместите всю логику в шаблон, и он быстро превратится в запутанный беспорядок разметки c & p, смешанной с условными выражениями. Для любого дублирования вы удвоите время, необходимое для его изменения. Добавьте встроенные стили и навязчивый Javascript, и вы в аду обслуживания. Maintenance

Если вы используете ООП для других частей вашего приложения, то почему вы считаете это процедурным, на ваш взгляд? Если вы поняли, что вы должны отделить Javascript и CSS от вашего HTML, зачем вам смешивать PHP с вашим шаблоном? Это не имеет смысла. Фрагмент кода OP - это сценарий, а не шаблон. Таким образом, это домен разработчика. И поэтому вы применяете всю хорошую практику, которую применяете к другим частям вашего приложения. И это включает в себя изоляцию логики в функциях и / или классах.

Конечно, дизайнер, изучающий сценарий, может не сразу знать, что происходит. Но опять же, она может не знать об этом, как только вы начнете добавлять нативные функции PHP. Что mb_strimwidth делает? И substr? Что это за конструкция ?:? Чем более актуальный PHP вы добавите, тем труднее будет читать не-разработчикам.

Если вы хотите, чтобы дизайнеры работали над шаблонами, не давайте им сценарии. Дайте им шаблоны. И если вы это сделаете, изолируйте логику от нее и замените ее простыми для понимания вызовами функций. Используйте имена функций, которые четко сообщают, что делает функция. Поэтому дизайнеру нужно только знать, «если я использую это с этим вводом, я всегда получу этот вывод. Мне все равно, каким будет этот вывод. Я оставлю это разработчику».

Разделение логики на функции (или классы) также дает вам немедленное преимущество в возможности проверить логику, используемую для визуализации отдельных частей на этой странице в изоляции. Вам не нужно настраивать всю среду, необходимую для создания страницы, а просто передать требуемый ввод и подтвердить его вывод (именно поэтому функция буферизует строку вместо ее вывода между прочим).

¹ Для тех из вас, кто считает, что это не проблема, я настоятельно рекомендую найти унаследованное приложение, которое действительно сохраняет всю логику в шаблоне представления. Попробуйте изменить несколько вещей. Как только вы получите удовольствие от перебора 2500 строк спагетти-кода, содержащих не менее 500 символов в каждой и содержащих смесь повторяющихся PHP, HTML, CSS и JavaScript, вы поймете, о чем я говорю.

9 голосов
/ 15 января 2011

Я не думаю, что вы пытаетесь достичь в представлении слишком много логики, но я думаю, что это должно быть несколько исправлено.

Что-то вроде:

<?php foreach($main as $item): ?>
<div class="item">
    <div class="name"><?php echo $item['name']; ?></div>
    <?php if($item['icq']): ?>
        <div class="phone"><?php echo $item['phone']; ?></div>
    <?php endif; ?>
</div>
<?php endforeach; ?>

Я считаю, что намного легче читать, и он выполняет ту же работу. Я также не думаю, что некодеру было бы трудно изменить, что в конечном итоге является целью представления.

2 голосов
/ 15 января 2011

Когда шаблонам нужно много логики, было бы полезно ввести шаблон ViewModel

Логика, которая определяет, когда отображается определенный блок, помещается в модель представления.

Пример
Фрагмент шаблона:

<?php if($item['show_phone_number']): ?>
    <div class="phone"><?php echo $item['phone_number']; ?></div>
<?php endif; ?>

Фрагмент модели просмотра:

$item['show_phone_number'] = $item["icq"] == '';
1 голос
/ 17 марта 2012

Представление не является шаблоном.

Или, по крайней мере, это не должен быть шаблон.Представления, как правило, являются экземплярами классов, которые отвечают за работу с логикой представления .Они манипулируют несколькими шаблонами и решают, какой из них использовать и какие данные передают в них.

Но у CI этого нет.Вы в основном застряли с шаблоном, который притворяется «представлением», и экземплярами ActiveRecord, которые, как они говорят, являются «моделями».Черт ... в собственном MVC Модель - это даже не конкретный класс, а прикладной уровень.

В долгосрочной перспективе такая ситуация вызовет логику представления и бизнес-логику в контроллер, одновременно создавая сложные в обслуживании шаблоны и классы активной записи.

1 голос
/ 15 января 2011

короткий ответ:

Насколько это возможно.

0 голосов
/ 15 января 2011

Ваши представления должны определенно содержать большинство тегов html, поэтому я не думаю, что функция get_items должна быть размещена где-то еще.Просто немного почистите ваши шаблоны и работайте с альтернативным синтаксисом цикла, как предложено Карпи.Вы могли бы также подумать об использовании какого-либо существующего движка шаблонов, такого как Twig, но с этим представления также должны содержать некоторые ссылки на ваши данные ... То, чего вы хотите добиться, - это то, что не кодировщики могут редактировать ваши html-файлы без необходимости пониматьмного скриптовой логики.

0 голосов
/ 15 января 2011

Я думаю, как Джеймс, слишком много кода, но вы можете добавить переменную массива в функцию get_items (), чтобы управлять префиксом и суффиксом каждого элемента, что-то вроде:

$options = Array('item_prefix' => '<div class="item">', 'item_suffix' => '</div>'...)
echo get_items();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...