Передать JSON, возвращенный Handlebars Helper, в качестве параметра в Handlebars Partial

Я хочу настроить частичное отображение общего настраиваемого модального окна. {{> myModal }}.

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

Я попробовал подход, рекомендованный здесь: Передача массива объектов в партиал - handlebars.js

Вот мой код из представления, которое вызывает частичное:

{{# getJsonContext '
    {
        "id": "deleteModal",
        "title": "Are you sure?",
        "formId": "delete-form",
        "body": "Press Yes to delete this record.  Press No to cancel."
    }
'}}

    {{> myModal this }}

{{/ getJsonContext }}

Вот мой помощник:

getJsonContext: function(data, options) {
        console.log(data);                     <-- The result is correct.
        let jsonReturn = JSON.parse(data);
        console.log(jsonReturn.title);         <-- The result is correct.
        return jsonReturn;
},

Вот мой частичный:

<div class="modal fade" id="{{ id }}">
  <div class="modal-dialog">
    <div class="modal-content">

        <!-- Modal Header -->
        <div class="modal-header bg-light">
            <h4 class="modal-title">{{ title }}</h4>
            <button type="button" class="close" data-dismiss="modal">&times;</button>
        </div>

        <!-- Form -->
        <form id="{{ formId }}" method="post">

            <!-- Modal body -->
            <div class="modal-body">
                {{ body }}
            </div>

            <!-- Modal footer -->
            <div class="modal-footer rounded-bottom bg-light">

            </div>

        </form>

    </div>
  </div>
</div>

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

Частичное, похоже, вообще не отображается. Когда я «Просмотр исходного кода страницы» в браузере, вместо всех частичных <html> отображается только [object Object].

Если я помещу {{> myModal this}} снаружи помощника, «Просмотр исходного кода страницы» покажет все модальные <html>,, но, естественно, идентификатор, заголовок, formId и тело будут пустыми (нулевыми).


person Jeff Matthews    schedule 10.12.2017    source источник
comment
Посмотрите еще раз на помощника getJsonContext в ответе, на который вы ссылались. Между return options.fn(JSON.parse(data)); в этом примере и оператором return в вашем очень большая разница.   -  person 76484    schedule 11.12.2017


Ответы (1)


После того, как я сломал себе мозг множеством проб, ошибок и исследований, я наконец обнаружил проблему. Мне пришлось передать JSON в качестве параметра named в вызове основного представления для частичного. Синтаксис должен был быть таким:

{{> jeff-modal <anyVariableName> = getJsonContext }}

Я закончил и заставил мой общий {{> jeff-modal }} принимать список кнопок, которые можно настроить.

Модальное окно теперь полезно как общее, настраиваемое, простое модальное окно, которое может быть отображено как частичное из любого представления, чтобы потребовать от пользователя нажатия одной из x-кнопок, чтобы сделать выбор.

Пример

Основное (вызывающее) представление имеет список записей журнала (транзакций) в порядке дат. Для каждой транзакции есть кликабельный значок «удалить». Модальное окно открывается, когда пользователь нажимает на значок. Когда модальное окно открыто, нам нужно знать, какую транзакцию удалить. У нас есть его _id.

После настройки таблицы и столбцов в <html> и запуска итератора {{# each }} значок «удалить» настраивается для каждой транзакции следующим образом. Обратите внимание, как значение data-id устанавливается в свойство транзакции _id:

<!-- table stuff up here -->

{{# each transactions}}    

  <tr class="journal-entry-row">

  <!-- some `<td>`'s -->

     <span class="journalData">
       <a href='#' class="open-deleteDialog"
                data-id="{{this._id}}" data-backdrop="static"
                data-toggle="modal" data-target="#deleteModal">

                     <span class="material-icons md-24 md-dark">delete</span>

       </a>
     </span>

  <!-- more table stuff -->

{{/ each }}

Иконки материалов, приведенные выше, можно найти здесь: https://material.io/icons/

"удалить" - это мусорная корзина.

Ниже приведен javascript для установки щелчка для всех мусорных баков. Обратите внимание, как _id транзакции совершает путешествие из <html> в javascript через data-id (выше). (Я думал, что это было довольно умно, кто бы это ни придумал.)

Кроме того, поскольку нашему пользовательскому модальному модулю было присвоено значение id формы удаления, мы можем заставить его установить модальное окно <form> action.

Наконец, добавлен небольшой CSS, чтобы выделить удаляемую строку.

$(document).on("click", ".open-deleteDialog", function () {

     var myTransactionId = $(this).data('id');

     // Set form action to call delete with _id parameter
     $("#delete-form").attr("action", "/transaction/delete?_id=" + myTransactionId );

     // Highlight the selected row.
     $(this).closest(".journal-entry-row").addClass("table-warning");

});

Теперь вернемся к вызывающему представлению после окончания <table>. Здесь вызывается модальное окно вспомогательного блока handlebars (но только при нажатии на корзину):

<!-- The Delete modal -->
{{# getJsonContext '
    {
        "id": "deleteModal",
        "title": "Are you sure?",
        "formId": "delete-form",
        "body": "Press \"Yes\" to delete this record.  Press \"No\" to cancel.",
        "buttons":
            [
                { "type": "submit", "onclick": "", "class": "btn btn-primary", "text": "Yes" },
                { "type": "button", "onclick": "removeHighlightEffect()", "class": "btn btn-secondary", "dataDismiss": "modal", "text": "No" }
            ]
    }'
}}

    {{> jeff-modal options = getJsonContext }}

{{/ getJsonContext }}

Вот помощник:

getJsonContext: function(data, options) {
        let jsonReturn = options.fn(JSON.parse(data));
        return jsonReturn;
},

Наконец, частичное {{> jeff-modal }}:

<div class="modal fade" id="{{ id }}">
   <div class="modal-dialog">
     <div class="modal-content">

        <!-- Modal Header -->
        <div class="modal-header bg-light">
            <h4 class="modal-title">{{ title }}</h4>
            <button type="button" class="close" data-dismiss="modal">&times;</button>
        </div>

        <!-- Form -->
        <form id="{{ formId }}" method="post">

            <!-- Modal body -->
            <div class="modal-body">
                {{ body }}
            </div>

            <!-- Modal footer -->
            <div class="modal-footer rounded-bottom bg-light">
                {{# each buttons }}
                    <button type = "{{ type }}" onclick = "{{ onclick }}" class = "{{ class }}" data-dismiss = "{{ dataDismiss }}" >{{ text }}</button>
                {{/ each }}
            </div>

        </form>

     </div>
   </div>
</div>

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

person Jeff Matthews    schedule 11.12.2017