Frage

This is my first MVC project from scratch and I'm trying to display multiple repeating record data in the view when it first loads and then allow the user to edit the fields on the same page when the edit button is clicked and save the data for that specific record. I have some of the data showing, but i feel like I'm going about it the wrong way.

This is my GeneRuleViewModel.cs

    public class GeneRuleViewModel
    {

    public virtual IEnumerable<GeneRule> GeneRules { get; set; }
    public virtual IEnumerable<GeneGroup> GeneGroups { get; set; }
    public List<KeyValuePair<int, string>> RuleDataStarDesignation { get; set; }
    public List<KeyValuePair<int, IEnumerable<SelectListItem>>> RuleDataPhenotype { get; set; }
    public List<KeyValuePair<int, bool>> RuleDataClinicallySignificant { get; set; }

    [DisplayName("Star Designation:")]
    public string StarDesignation { get; set; }
    [DisplayName("Phenotype:")]
    public string SelectedPhenotype { get; set; }
    [DisplayName("ClinicallySignificant?")]
    public bool ClinicallySignificant { get; set; }
    }

I used a KeyValuePair so that when looping through the items in the view I could know which value belonged to the specific GeneRule_ID

This is my Index() method in the GeneRuleController.cs where I am populating the KeyValuePairs from the repository

        public ActionResult Index()
    {
        var geneRules = generuleRepository.GetGeneRules();
        var geneGroups = generuleRepository.GetGeneGroups();

        List<KeyValuePair<int, string>> ruleStarDesignation = new List<KeyValuePair<int, string>>();
        List<KeyValuePair<int, IEnumerable<SelectListItem>>> rulePhenotype = new List<KeyValuePair<int, IEnumerable<SelectListItem>>>();
        List<KeyValuePair<int, bool>> ruleClinicallySignificant = new List<KeyValuePair<int, bool>>();


        foreach (var rule in geneRules)
        {
            rulePhenotype.Add(new KeyValuePair<int, IEnumerable<SelectListItem>>((int)rule.GeneRule_ID, generuleRepository.GetRulePhenotypes(rule)));
            ruleStarDesignation.Add(new KeyValuePair<int, string>((int)rule.GeneRule_ID, generuleRepository.GetRuleStarDesignation(rule)));
            ruleClinicallySignificant.Add(new KeyValuePair<int, bool>((int)rule.GeneRule_ID, generuleRepository.GetRuleClinicalSignificance(rule)));       
        }

        var generuleViewModel = new GeneRuleViewModel();
        generuleViewModel.GeneRules = geneRules;
        generuleViewModel.GeneGroups = geneGroups;
        generuleViewModel.RuleDataStarDesignation = ruleStarDesignation;
        generuleViewModel.RuleDataPhenotype = rulePhenotype;
        generuleViewModel.RuleDataClinicallySignificant = ruleClinicallySignificant;


        return View(generuleViewModel);
    }

This is my Index.cshtml where I am looping through each GeneGroups and GeneRules to display the data

    <div id="generulesgrid">
    <span class="glyphicon glyphicon-filter"></span>&nbsp;<span class="h4">Rule Filter</span>
    <div class="btn-group rulefilter">
        <button type="button" class="filter btn btn-default" data-filter="all">Show All</button>         
        @foreach (var geneGroup in Model.GeneGroups) {    
            <button type="button" class="filter btn btn-default" data-filter="@Html.DisplayFor(x => geneGroup.GeneGroup_NM)">@Html.DisplayFor(x => geneGroup.GeneGroup_NM)</button>
        }
    </div>


@foreach (var geneGroup in Model.GeneGroups) {    
    <div class="mix @Html.DisplayFor(x => geneGroup.GeneGroup_NM)">
        <div class="row">
            <div class="col-md-12">
                <div class="page-header">
                   <span class="glyphicon glyphicon-list"></span>&nbsp;<span class="h4">Gene Rules for <small>@Html.DisplayFor(x => geneGroup.GeneGroup_NM)</small></span>                
                </div>
            </div>
        </div>

        <div class="row">
            @foreach(var geneRule in Model.GeneRules.Where(x => x.GeneGroup_ID == geneGroup.GeneGroup_ID))
            {
                <div class="col-md-4">
                    @using (Html.BeginForm(null, "generule", FormMethod.Post, new { @class = "form-horizontal", @role = "form" }))
                    {
                        <div class="panel panel-default">
                            <div class="panel-heading">
                                @Html.DisplayFor(x=> geneRule.GeneRule_NM) <span class="glyphicon glyphicon-edit pull-right editRule" data-toggle="tooltip" title="Edit Rule"></span>
                            </div>
                            <div class="panel-body">
                                <div class="form-group">
                                    @Html.LabelFor(x => x.StarDesignation, new { @class = "col-md-4 control-label" })
                                    <div class="col-md-8">
                                        @Html.TextBoxFor(x => x.StarDesignation, new {@Value = Model.RuleDataStarDesignation.Where(x => x.Key == geneRule.GeneRule_ID).FirstOrDefault().Value, @class = "form-control", @placeholder = "Enter Star Designation"})
                                    </div>
                                </div>

                                <div class="form-group">
                                    @Html.LabelFor(x => x.SelectedPhenotype, new { @class = "col-md-4 control-label" })
                                    <div class="col-md-8">
                                        @Html.DropDownListFor(x=>x.SelectedPhenotype,Model.RuleDataPhenotype.Where(x => x.Key == geneRule.GeneRule_ID).FirstOrDefault().Value,"select phenotype",new {@id = "generule_" + geneRule.GeneRule_ID + "_phenotype", @class = "form-control" })
                                    </div>
                                </div>
                                <div class="form-group">                                    
                                    @Html.Label("Rule Definition","Rule Definition:",new { @class = "col-md-4 control-label" })
                                    <div class="col-md-8">
                                    </div>
                                </div>

                                <div class="form-group">
                                    <div class="checkbox">
                                        <label>                                        
                                            @Html.CheckBoxFor(x=> x.ClinicallySignificant, Model.RuleDataClinicallySignificant.Where(y => y.Key == geneRule.GeneRule_ID).FirstOrDefault().Value)

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

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


}
</div>

As I said, I feel as though that I'm going about this the wrong way, so any help/advice would be greatly appreciated.

War es hilfreich?

Lösung

It looks decent to me, my approach would have been a bit different; I would have create a partial view for each sub-list in the model that way each partial view takes a simple strongly typed list.

However, your way can also work. Keep in mind (lots of MVC rookies make this mistake), your ViewModel does not have to match the model you bind to when you submit changes.

If you want to be even more slick, you can use AJAX and avoid complicated binding later (but you will have to set up the AJAX which takes some time also).

Edit: If you want the easiest approach, put an edit button with a proper id beside each item you wish to edit, this makes it super-easy to find the item you are editing.

Edit 2: Some nice example here: How to bind multiple textbox with ViewModel array string property?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top