Как передать массив в шаблон в качестве атрибута, а затем использовать массив, а затем использовать шаблон рекурсивно? - PullRequest
0 голосов
/ 05 февраля 2019

Я работал с ColdFusion CFML в течение нескольких месяцев после использования JSP в течение нескольких лет, и все еще есть некоторые вещи, которые мне трудно понять на этом языке.Google, CFDocs и Adobe не помогли с этим конкретным вопросом.

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

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

Я прочитал несколько статей, в которых объясняется, как создать CFModule, ноНикто не говорит, как на самом деле использовать атрибут, который вы передаете его.Вот одна из вещей, которые я попробовал:

(в исходном шаблоне):

<h4>Comments</h4>
<div id="comments" name="comments">
  <cfmodule template="comments.cfm" comments="#Variables.page.comments#">
</div>

(в шаблоне, который я хочу в конечном итоге вызвать рекурсивно):

<cfoutput>
  <cfloop array = "#comments#" index = "comment">
    <div>#comment.commenter_name# says</div>
    <div>#comment.created#</div>
    <div>#comment.content#</div>
  </cfloop>
</cfoutput>

Я не могу просто использовать Variables.page.comments во втором шаблоне, потому что шаблон будет вызывать себя рекурсивно;например, я хочу, чтобы массив в Variables.page.comments[2].comments в следующий раз, Variables.page.comments[2].comments[5].comments в следующий раз и т. д.

1 Ответ

0 голосов
/ 05 февраля 2019

Вы можете создать свое иерархическое представление, обернув логику рендеринга вокруг

<cfscript>
    cfsavecontent variable="html" {
       do logic stuff here
    }
    writeOutput(html);
<cfscript>

, которая сохранит ваш вывод в переменную.Затем выведите переменную.

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

string function outputComments (
    required array comments) {
    var html = "";
    for (var comment in arguments.comments) {
        html &= "<li>#comment.message#";
        if (comment.children.length) {
            html &= outputComments(comment.children);
        }
        html &= "</li>";
    }
    if (html != "") {
        html = "<ul>#html#</ul>";
    }
    return html;
}

writeOutput(outputComments(comments));

Проделав кучу такой работы, вы можете захотетьрассмотреть вопрос об отображении ваших комментариев / ответов в каком-то JavaScript-виджете, управляемом ajax, используя сервис, который возвращает данные комментариев в JSON, где вы одновременно получаете страницу комментариев или ответов.Я написал виджет комментариев в стиле Facebook, который работал таким образом, и преимущество в том, что вам не нужно беспокоиться о размере разговора.

...