Как получить доступ к модели частичного представления в родительском представлении? - PullRequest
0 голосов
/ 26 апреля 2020

У меня было представление, которое содержало следующий скрипт:

$(document).ready(function () {
    var messages = @Html.Raw(Json.Encode(Model.Messages)); // Accessing the Model here.
    $.each(messages, function (index, item) {
        addMessageRow(item, false);
    });
    $("#btnAddMessage").on("click", function () {
        addMessageRow();
    });
    // More code
});

.., который работал просто отлично. Затем я преобразовал его в частичное представление, отображаемое в модальном bootstrap. Насколько я знаю, секция скрипта не работает в модальном / частичном представлении (и это не так). Итак, я переместил код javascript в родительское представление, которое будет выполнено сразу после вызова метода .modal:

$("a[data-modal]").on("click", function () {
    $("#childModalContent").load(this.href, function () {
        $("#childModal").modal({ keyboard: true }, "show");

        var messages = /*GetMessagesAsJson();*/          // How to get the Messages here?
        $.each(messages, function (index, item) {
            addMessageRow(item, false);
        });
        $("#btnAddMessage").on("click", function () {    // This works just fine.
            addMessageRow();
        });

    });
    return false;
});

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

public ActionResult Edit(int? parentId, int? childId)
{
    if (parentId == null || childId == null) { /*BadRequest*/ }

    child child = GetChild(parentId, childId);
    if (child == null) { /*NotFound*/ }

    return PartialView("_Edit", child);
}

А вот как называется действие:

@Html.ActionLink("Edit", "Edit", "ControllerName", 
                 new {parentId = Model.ParentId, childId = item.Id },
                 new { @class = "btn btn-default", data_modal = "" })

Как показывает функция .on("click"), указанная выше, при нажатии на эту ссылку загружается частичный вид как модель. Чтобы это работало, у меня есть следующий заполнитель в родительском представлении:

<div id="childModal" class="modal fade in">
    <div class="modal-dialog">
        <div class="modal-content">
            <div id="childModalContent"></div>
        </div>
    </div>
</div>

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

Как выполнить javascript код в частичном (модальном) виде доступа к его модели?

Ответы [ 2 ]

1 голос
/ 26 апреля 2020

Сценарий 1 - Данные в частичном представлении имеют статус c, т. Е. Модель данных частичного представления не изменяется после загрузки родительского представления

  • Из действия метод, возвратное представление не частичное представление
  • Создайте другое частичное представление, которое принимает ту же модель, что и частичное представление. Поместите все JS код здесь
  • Теперь у нас есть два частичных представления. Один с HTML и другой с JS кодом. Вызовите их обоих из родительского представления. HTML частичное представление будет go внутри кода HTML и JS частичное представление будет go в разделе сценариев.
  • Частичное представление с кодом JS такое же, как и любое другое частичное просматривать, но имеет только код JS. См. Пример ниже

Вот пример в. net core:

Метод действия

 public async Task<IActionResult> Search(SearchModel model)
    {
        var vm = _someService.GetData(model);

        return View(vm);

    }

Родительский вид

@model SomeViewModelOfYourChoice


<section class="filter-section">
   //Render HTML partial view
   @{ await Html.RenderPartialAsync("_SearchResultsFiltersPartial", Model); }
</section>

@section scripts{
    //Render JS code partial view
    @{ await Html.RenderPartialAsync("_SearchResultsScriptsPartial", Model); }

}

Частичное представление с JS только кодом

@model PartialViewModelOfYourChoice

<script>
 $(document).ready(function () {
     // Model is now available here e.g. @Model   
     //All your JS code here
 });
</script>

Сценарий 2. Данные в частичном представлении являются динамическими c, т.е. данные изменяются каждый раз при загрузке частичного представления

  • Возврат JSON из вашего метода действия, а не частичного просмотра (см. Пример ниже)
  • Не передавайте никакую модель в частичном представлении
  • Вкл bootstrap модальный show event получить данные из действия и установить результат (JSON) в переменной
  • Запустить код JS с результатом (JSON)

Здесь является примером

Возвращает JSON из метода действия

public ActionResult Edit(int? parentId, int? childId)
{
   if (parentId == null || childId == null) { /*BadRequest*/ }

   child child = GetChild(parentId, childId);
   if (child == null) { /*NotFound*/ }

   return Json(child,JsonRequestBehavior.AllowGet);
}

Родительское представление

@model SomeViewModelOfYourChoice


<section class="filter-section">
   //Render HTML partial view. Note that model is not passed here
   @{ await Html.RenderPartialAsync("_SearchResultsFiltersPartial"); }
</section>        
}

При щелчке якоря вызывайте метод действия.

//Generate the URL
// I believe that Model.ParentId will remain the same but you need to dynamically pass the item.id
var url = '@Html.Raw(Url.Action("Edit", "ControllerName", new {parentId = Model.ParentId, childId = item.Id }))';
// Call action method
$.ajax({url: url,type: 'GET',contentType: 'application/json; charset=utf-8',
        success: function (result) {
            messages = result;
            //Run your rest of the JS code here   
         }
       });
0 голосов
/ 28 апреля 2020

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

Итак, вот что я сделал. Сначала я добавил действие для возврата дочернего объекта:

public ActionResult GetChild(int id)
{
    var child = _context.ChildEntityDbSet.Find(id);
    if (child == null) { return HttpNotFound(); }

    return this.JsonEx(child, JsonRequestBehavior.AllowGet);
}

.. затем к этому действию делается вызов для извлечения этого объекта при каждом нажатии ссылки «Редактировать» для отображения модального вида:

var currentChild;

$("a[data-modal]").on("click", function () {
    currentChild = null;
    var childId = $(this).attr("data-child-id");
    var modalUrl = this.href;

    $.ajax({
        url: "/ControllerName/GetChild/" + childId
    })
    .done(function (data) {
        currentChild = data;
        if (currentChild != null) { showModal(modalUrl); }
    })
    .fail(function () {
        // Handle
    });

    return false;
});

И затем я получаю доступ к messages через объект currentChild вместо Модели:

$("#childModal").on("show.bs.modal", function () {
    // Add existing messages as rows.
    if (currentChild != null) {
        var messages = currentChild.messages;
        $.each(messages, function (index, item) {
            addMessageRow(item, false);
        });
    }

    $("#btnAddMessage").on("click", function () {
        addMessageRow();
    });
    // More code
});

Я все еще надеюсь, что кто-то может найти лучшее решение.

...