如何使Ajax下拉列表牢固绑定到ASP.Net MVC 5中的ViewModel [英] How to make an ajax dropdown strongly bound to the ViewModel in ASP.Net MVC 5

查看:59
本文介绍了如何使Ajax下拉列表牢固绑定到ASP.Net MVC 5中的ViewModel的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我有一份求职申请的推荐表格.现在,当求职者从公司下拉列表中选择公司时,我想显示仅针对该公司的封面下拉列表(封面已经由候选人从另一个选项卡上载).现在,要想成为Microsoft的推荐人,一个人可能会有3个封面.

So, I have a referral form for job application. Now when a job seeker selects a company from a company dropdown, I want to display the dropdown of coverletters just for that company (coverletters are already uploaded by candidate from another tab). Now for getting referred for Microsoft a person might have 3 coverletters.

我想知道如何显示来自ajax调用的下拉列表,并且仍然使Coverletter下拉列表牢固地绑定到模型.

I want to know how to can I display the dropdown from ajax call and still keep the coverletter dropdown strongly bound to the Model.

以下是非AJAX 的强约束:显示所有封面,与选择的公司无关)

Below is Non AJAX strongly Bound: shows all the coverletters irrespective of company selected)

@model Bridge.ViewModels.ReferralViewModel
@using (Html.BeginForm())
{
        <div class="form-group">
            @Html.LabelFor(model => model.CompanyId, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownListFor(m => m.CompanyId, Model.Companies, new { @class = "form-control js-change", onchange = "companyChanged()" })
            </div>
        </div>
        <div class="form-group">
            @Html.LabelFor(model => model.CoverLetterId, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownListFor(m => m.CoverLetterId, new SelectList(Model.CoverLetters, "CoverLetterId", "CoverLetterName", Model.CoverLetters), new { @class = "form-control" })
            </div>
        </div>
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

型号:

   public class ReferralViewModel
    {
        public int ReferralViewModelId { get; set; }
        public int CompanyId { get; set; }
        public IEnumerable<SelectListItem> Companies { get; set; }
        public int CoverLetterId { get; set; }
        public IEnumerable<CoverLetter> CoverLetters { get; set; }
    }

控制器:

        public ActionResult Create()
    {
        var viewModel = new ReferralViewModel
        {
            var candidateId = User.Identity.GetUserId();
            Companies = _context.Companies.Select(x => new SelectListItem
            {
                Text = x.CompanyName,
                Value = x.CompanyId.ToString()

            }),
            CoverLetters = _context.CoverLetters.Where(r => r.CandidateId == candidateId).ToList()
        };
    return View(viewModel);
}

现在尝试AJAX:

控制器操作

public JsonResult ListOfCoverLetterByCompanyId(int companyId)
        {
            var coverletters = _context.CoverLetters
                .Where(c => c.CompanyId == companyId)
                .ToList();

            var dropdown = new List<SelectListItem>();
            foreach (var cl in coverletters)
            {
                dropdown.Add(new SelectListItem { Text = cl.CoverLetterName, Value = cl.CoverLetterId.ToString() });
            }
            return Json(dropdown, JsonRequestBehavior.AllowGet);
        }

新视图

@model Bridge.ViewModels.ReferralViewModel
@using (Html.BeginForm())
{
            @Html.LabelFor(model => model.CompanyId, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownListFor(m => m.CompanyId, Model.Companies, new { @class = "form-control js-change", onchange = "companyChanged()" })
            </div>
        </div>
        @* Dropdown will appear here*@
        <select id="CoverLetterId" name="CoverLetterId"></select>
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

@section scripts{
    <script>
        function companyChanged() {
            var companyId = $(".js-change").val();
            $.ajax({
                url: "/Referral/ListOfCoverLetterByCompanyId",
                data: { companyId: companyId },
                contentType: "application/json; charset-utf-8",
                success: function (datas) {
                        $("#CoverLetterId").html("");
                    $.each(datas, function (i, data) {
                        $("#CoverLetterId ").append('<option value="' + data.Value + '">' + data.Text + '</option>');
                    });
                },
                error: function () {}
            });
        }
    </script>
    <script>
        companyChanged();
    </script>
}

新视图模型

   public class ReferralViewModel
    {
        public int ReferralViewModelId { get; set; }
        public int CompanyId { get; set; }
        public IEnumerable<SelectListItem> Companies { get; set; }
        public int CoverLetterId { get; set; }
    }

我认为通过遵循当前代码,我失去了强烈绑定的Razor视图的美丽.下拉列表不受任何属性的约束.我能以某种方式使其牢固绑定并使用 @ Html.DropdownListFor

I think by following current code I lost the beauty of strongly bound Razor view. Dropdown is not bound to any property. Can I somehow make it strongly bound and use @Html.DropdownListFor

推荐答案

您的原始视图模型是正确的,尽管最好将CoverLetters属性设置为public IEnumerable<SelectListItem> CoverLetters { get; set; },并且将CompanyIdCoverLetterId属性应为int?(可为空)

Your original view model is correct although it would be better for your CoverLetters property to be public IEnumerable<SelectListItem> CoverLetters { get; set; }, and both the CompanyId and CoverLetterId properties should be int? (nullable)

并在视图中使用牢固地绑定到模型

and in the view, strongly bind to your model using

@Html.DropDownListFor(m => m.CoverLetterId, Model.CoverLetters, "Please select", new { @class = "form-control" })

在您的控制器中,添加一个用于初始化两个SelectList的私有方法.如果CompanyId具有值,则从数据库填充CoverLetters,否则将其初始化为空集合.然后,如果ModelState无效,则可以在GET方法和POST方法中调用该方法

In your controller, add a private method that initializes both SelectLists. If CompanyId has a value, then your populate CoverLetters from the database, otherwise you initialize it to an empty collection. You can then call that method in both the GET method, and in the POST method if ModelState is invalid

private void ConfigureViewModel(ReferralViewModel model)
{
    // Populate companies always
    model.Companies = _context.Companies.Select(x => new SelectListItem
    {
        Text = x.CompanyName,
        Value = x.CompanyId.ToString()
    });
    // Populate cover letters only if a company has been selected
    // i.e. if your editing and existing Referral, or if you return the view in the POST method
    if (model.CompanyId.HasValue)
    {
        model.CoverLetters = _context.CoverLetters.Where(x => x.CompanyId == model.CompanyId.Value).Select(x => new SelectListItem
        {
            Value = x.CoverLetterId.ToString(),
            Text = x.CoverLetterName
        });
    }
    else
    {
        model.CoverLetters  = new SelectList(Enumerable.Empty<SelectListItem>());
    }
}

public ActionResult Create()
{
    ReferralViewModel model = new ReferralViewModel();
    ConfigureViewModel(model);
    return View(model);
}

public ActionResult Create(ReferralViewModel model)
{
    if (!ModelState.IsValid())
    {
        ConfigureViewModel(model);
        return View(model);
    }
    // Initialize data model, map properties from view model, save and redirect
}

这篇关于如何使Ajax下拉列表牢固绑定到ASP.Net MVC 5中的ViewModel的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆