简体   繁体   English

Asp.net MVC 核心,从 PopupView 发布以前的 ViewModel

[英]Asp.net MVC core, posting previous ViewModel from PopupView

Maybe I'm looking at this the wrong way, maybe the fact that the browser is showing the view as a pop up doesn't change the fact that for MVC this is just a different View with it's own ViewModel.也许我以错误的方式看待这个问题,也许浏览器将视图显示为弹出窗口这一事实并没有改变这样一个事实,即对于 MVC 这只是一个具有自己的 ViewModel 的不同视图。 Since this is a form inside a form in a way, maybe there are better ways to do the following;由于这是某种形式的形式,因此也许有更好的方法来执行以下操作;

The initial view (CreateTimeslot.cshtml) is a form with properties of a workshop to be scheduled.初始视图 (CreateTimeslot.cshtml) 是一个表单,其中包含要安排的研讨会的属性。 name, description,.., And a speaker multiselect list:名称,描述,..,以及演讲者多选列表:

@model MDFrontend.Models.Timeslots.TimeslotManagementViewModel
<div class="form-group">
            <label asp-for="StartTime" class="control-label"></label>
            <input asp-for="StartTime" type="datetime" class="form-control" value="@startTime" />
            <span asp-validation-for="StartTime" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="EndTime" class="control-label"></label>
            <input asp-for="EndTime" type="datetime" class="form-control" value="@startTime.Add(Model.WorkshopDuration)" readonly />
            <span asp-validation-for="EndTime" class="text-danger"></span>
        </div>

        <!--------------------------------------------------------------SpeakerBox---------------------------------------------------------------------->
        <div class="form-group">
            <label asp-for="Speakers" class="control-label"></label>
            <select asp-for="SpeakerIDs" id="speakerBox" name="SpeakerIDs[]" asp-items="@Model.Speakers" multiple="multiple">
            </select>
            <span asp-validation-for="SpeakerIDs" class="text-danger"></span> <!--This is not showing, asp-validation-summary does-->
        </div>

        <button onclick="showFormInPopup('@Url.Action("CreateSpeaker","SpeakerAdmin",Model,Context.Request.Scheme)',
                                                        'New Speaker')" type="button" id="btnAddSpeaker" class="btn btn-primary"> @Localizer["Add_Speaker"]
        </button>

I'm passing the TimeslotManagementViewModel in the Url.Action method, which I'm mapping to the CreateSpeakerViewModel我在 Url.Action 方法中传递 TimeslotManagementViewModel,我将其映射到 CreateSpeakerViewModel

public class CreateSpeakerViewModel
{
    public string Firstname { get; set; }

    public string Lastname { get; set; }

    public TimeslotManagementViewModel oldModel { get; set; }
}

This view is shown as a popup:此视图显示为弹出窗口:

<!-------------------------------------------Hidden Add Speaker Popup--------------------------------------------------->

    <div class="modal" tabindex="-1" role="dialog" id="form-modal">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title"></h5>
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <div class="modal-body">

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

<!-------------------------------------------Hidden Add Speaker Popup--------------------------------------------------->

The body of this CreateSpeaker View:这个 CreateSpeaker 视图的主体:

@model MDFrontend.Models.Speakers.CreateSpeakerViewModel
<form asp-action="CreateSpeaker" asp-controller="SpeakerAdmin">
        <div asp-validation-summary="ModelOnly" class="text-danger"></div>
        <div class="form-group">
            <label asp-for="Firstname" class="control-label"></label>
            <input asp-for="Firstname" class="form-control" />
            <span asp-validation-for="Firstname" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="Lastname" class="control-label"></label>
            <input asp-for="Lastname" class="form-control" />
            <span asp-validation-for="Lastname" class="text-danger"></span>
        </div>
        
        <div class="form-group" >
            <input type="submit" value="Save" asp-action="CreateSpeaker" asp-controller="SpeakerAdmin" 
                    formmethod="post" class="btn btn-primary" />
        </div>
    </form>

The CreateSpeaker Post method is receiving this simple form, adding them to the db, redirecting to the initial CreateTimeslot view with an updated multiselect. CreateSpeaker Post 方法正在接收这个简单的表单,将它们添加到数据库,重定向到具有更新的多选的初始 CreateTimeslot 视图。

[HttpPost]
    [Authorize(Roles = RoleConstant.Admin)]
    public async Task<IActionResult> CreateSpeaker(CreateSpeakerViewModel vm, 
   TimeslotManagementViewModel model)
    {
    //The idea would be to have TimeslotManagementViewModel model posted back with the set values by the user before "AddSpeaker" was clicked.
 }

However with this solution the previous set inputs are lost to the user.但是,使用此解决方案,用户将丢失先前设置的输入。 So atm I'm thinking either to use map every property of the TimeslotManagementViewModel to the CreateSpeakerViewModel to pass them between controllers or maybe an Ajax call could work or drop the popup all togheter.所以 atm 我正在考虑使用 map TimeslotManagementViewModel 的每个属性到 CreateSpeakerViewModel 以在控制器之间传递它们,或者 Ajax 调用可以工作或将弹出窗口全部删除。 Or better yet someone here knows a better option?或者更好的是这里有人知道更好的选择?

Many thanks!非常感谢!

After some trail and error realized the best, maybe only solution comes by using some simple Javascript.经过一些试验和错误实现了最好的,也许唯一的解决方案是使用一些简单的 Javascript。

function SaveSpeaker(e) {

var firstname = $('#txtFirstname').val();
var lastname = $('#txtLastname').val();

$.ajax({
    url: '/SpeakerAdmin/CreateSpeaker',
    dataType: 'Json',
    type: "POST",
    data: { firstname: firstname, lastname: lastname },
    success: function (data, status, jqXHR) {
        console.log('success');
        if (data.valFirstname == false) {
            $('#valFirstname').text('Firstname not complete');
        }
        if (data.valLastname == false) {
            $('#valLastname').val('Lastname not complete')
        }
        if (data.valSpeaker == true) {
            $('#form-modal').modal('hide');
            $('#valSpeaker').text('Speaker added');
            $('#speakerBox').append(new Option(firstname + " "  + lastname, data.speakerID))
        }
        
    },
    error: function (jqXHR, status, err) {
        
    },
    complete: function (jqXHR, status) {
        
    }
});

So instead of posting the form just using an Ajax call to post to the controller and return Json to populate the new select option.因此,不是仅使用 Ajax 调用来发布表单,而是发布到 controller 并返回 Json 以填充新的 select 选项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM