Frage

Relativ neu in MVC und der Versuch, eine kaskadierende Dropdown -Liste für Zugzeiten zu erhalten.

Nachdem Sie sich viele Beiträge angesehen haben, sagen die Leute, dass Sie sich von Viewbag/ViewData fernhalten und sich stattdessen auf ViewModels konzentrieren sollten, aber ich kann einfach nicht meinen Kopf um ihn herum bringen, und es treibt mich die Wand hoch. Jedes Tutorial scheint entweder komplex oder zu einfach zu sein, und die gesamte ViewModel -Idee hat mich noch nicht mit mir geklickt.

Hier ist also mein Szenario: Ich habe ein Administratorsystem, in dem Mitarbeiter einzelne Zugreisen hinzufügen können. Für jede Zugzeit habe ich ein Eingabeformular, in dem der Benutzer ein Unternehmen auswählen kann, und von dort aus möchte ich, dass die Dropdown -Liste darunter mit einer Liste von Reisenummern gefüllt ist, die Routen anzeigen. Sobald sie eine Zahl ausgewählt haben, können sie den Rest der Form weitermachen, die ziemlich groß ist, einschließlich der Reisezeit, Einrichtungen im Zug usw.

Ich habe ein ViewModel wie SO erstellt:

public class JourneyNumbersViewModel
    {
        private List<SelectListItem> _operators = new List<SelectListItem>();
        private List<SelectListItem> _journeys= new List<SelectListItem>();

        [Required(ErrorMessage = "Please select an operator")]
        public string SelectedOperator { get; set; }
        [Required(ErrorMessage = "Please select a journey")]
        public string SelectedJourney { get; set; }

        public List<SelectListItem> Journeys
        {
            get { return _journeys; }
        }
        public List<SelectListItem> Operators
        {
            get
            {
                foreach(Operator a in Planner.Repository.OperatorRepository.GetOperatorList())
                {
                    _operators.Add(new SelectListItem() { Text = a.OperatorName, Value = a.OperatorID.ToString() });
                }
                return _operators;
            }
        }
    }

In meinem Controller habe ich dies für die Ansicht erstellen:

    public ActionResult Create()
    {
        return View(new JourneyNumbersViewModel());
    }

Und hier funktioniert es nicht wirklich für mich - wenn ich mein Modell oben in der Ansicht erstellen zu ändern: @model Planner.ViewModels.JourneyNumbersViewModel, Dann wirft der Rest meiner Form Fehler, da das Modell für den Rest der Form nicht mehr korrekt ist. Soll es so funktionieren - was ist, wenn Sie mit einer einzigen Ansicht auf mehrere Ansichtsmodelle verweisen müssen?

Ich weiß .

War es hilfreich?

Lösung

Ich habe etwas Ähnliches getan. Hier ist ein Teil des Code (Entschuldigung im Voraus dafür, dass dies ziemlich lange ist, aber ich wollte sicherstellen, dass Sie dies auf Ihrer Seite neu erstellen können):

Aussicht sieht so aus:

using Cascading.Models
@model CascadingModel


@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Cascading Forms</h2>
<table>

@using(Html.BeginForm("Index", "Home"))
{
<tr>
    <td>@Html.LabelFor(m=>m.CategoryId)</td>
    <td>@Html.DropDownListFor(m => m.CategoryId, new SelectList(Model.Categories, "Id", "Name"), string.Empty)</td>
</tr>
<tr>
    <td>@Html.LabelFor(m=>m.ProductId)</td>
    <td>@Html.CascadingDropDownListFor(m => m.ProductId, new SelectList(Model.Products, "Id", "Name"), string.Empty, null, "CategoryId", "Home/CategorySelected")</td>
</tr>
<tr>
    <td>&nbsp;</td>
    <td><input type="submit" value="Go"/></td>
</tr>
}
</table>

Das Modell sieht wie folgt aus:

public class CascadingModel
{
    public int CategoryId { get; set; }
    public List<Category> Categories { get; set; }
    public int ProductId { get; set; }
    public List<Product> Products { get; set; }
}

Der echte "clevere" Teil des Systems ist die html.cascadingdropdown -Liste für die Aussicht wie folgt:

public static class MvcHtmlExtensions
{
    public static MvcHtmlString CascadingDropDownListFor<TModel, TProperty>(
        this HtmlHelper<TModel> htmlHelper,
        Expression<Func<TModel, TProperty>> expression,
        IEnumerable<SelectListItem> selectList,
        string optionLabel,
        IDictionary<string, Object> htmlAttributes,
        string parentControlName,
        string childListUrl
        )
    {
        var memberName = GetMemberInfo(expression).Member.Name;

        MvcHtmlString returnHtml = Html.SelectExtensions.DropDownListFor(htmlHelper, expression, selectList, optionLabel, htmlAttributes);

        var returnString = MvcHtmlString.Create(returnHtml.ToString() + 
                    @"<script type=""text/javascript"">
                        $(document).ready(function () {
                            $(""#<<parentControlName>>"").change(function () { 
                                var postData = { <<parentControlName>>: $(""#<<parentControlName>>"").val() };
                                $.post('<<childListUrl>>', postData, function (data) {
                                    var options = """";
                                    $.each(data, function (index) {
                                        options += ""<option value='"" + data[index].Id + ""'>"" + data[index].Name + ""</option>"";
                                    });
                                    $(""#<<memberName>>"").html(options);
                                })
                                .error(function (jqXHR, textStatus, errorThrown) { alert(jqXHR.responseText); });
                            });
                        });
                     </script>"
                    .Replace("<<parentControlName>>", parentControlName)
                    .Replace("<<childListUrl>>", childListUrl)
                    .Replace("<<memberName>>", memberName));

        return returnString;

    }

    private static MemberExpression GetMemberInfo(Expression method)
    {
        LambdaExpression lambda = method as LambdaExpression;
        if (lambda == null)
            throw new ArgumentNullException("method");

        MemberExpression memberExpr = null;

        if (lambda.Body.NodeType == ExpressionType.Convert)
        {
            memberExpr = ((UnaryExpression)lambda.Body).Operand as MemberExpression;
        }
        else if (lambda.Body.NodeType == ExpressionType.MemberAccess)
        {
            memberExpr = lambda.Body as MemberExpression;
        }

        if (memberExpr == null)
            throw new ArgumentException("method");

        return memberExpr;
    }
}

Controller -Logik für diejenigen, die danach suchen:

public ActionResult CategoriesAndProducts()
{
    var viewModel = new CategoriesAndProductsViewModel();
    viewModel.Categories = FetchCategoriesFromDataBase();
    viewModel.Products = FetchProductsFromDataBase();
    viewModel.CategoryId = viewModel.Categories[0].CategoryId;
    viewModel.ProductId = viewModel.Products.Where(p => p.CategoryId).FirstOrDefault().ProductId;
    return View(viewModel);
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top