ASP.Net MVC Update ViewModel on DropDown Selection

2019-02-14 20:03发布

问题:

At first I'm absolutely new on web development. I'm trying to develop a Web application which consists of a single page (I started with an empty project trying to follow the mvc pattern).

To populate my View I pass a ViewModel through my HomeController to my "Home"View.

Now I want to change a few Label-Texts depending on a DropDown selection.

ViewModel:

public IEnumerable<Models.Language> AvailableLanguages;
public Models.Language SelectedLanguage
Public IEnumerable<Models.Text> Content;

Language:

public int ID;
public string LanguageText;

Text:

public Language Language;
public string Description;

HTML: @model ViewModels.MyViewModel

<div>
    @Html.DropDownFor(x => x.AvailableLanguages, 
    new SelectList(Model.AvailableLanguages, 
    "ID", 
    "LanguageText", 
    new {@onchange= ... })) 
</div>

<div>
    @{
        @:@Model.MyViewModel.Content
        .Where(o => o.Language.Equals(Model.SelectedLanguage)
        .First())
        .Description
     }
</div>

I read something about this "@onchange" attribute (Ajax, JQuery) - but to be honest It'd be great if there would be any ASP/MVC/HTML solution to achive my goal - to update my SelectedLanguage Property everytime the selected item of the dropdown gets changed.

Additionaly: Is there a tutorial for webdevelopment (asp, html, ajax, jquery, js) you can recommend?

Thanx!

EDIT

Now I tried to implement the code provided but it seems that nothing happens when changing the selected item...

Script:

<div class="LanguageSelection">
        @{
            @Html.DropDownList("SelectedLanguage", new SelectList(Model.AvailableLanguages, "ID", "Description"))
            <script src="~/Scripts/jquery-1.10.2.min.js" type="text/javascript">
                var url = '@Url.Action("ChangeLanguage", "Home")';
                $('#SelectedLanguage').change() {
                    $.getJSON(url, {
                        ID: $(this).val() 
                    }, function(response){
                        $('#Title').text(response.Title);   
                    });
                };
            </script>
        }
    </div>

JsonResult:

public JsonResult ChangeLanguage(int id) {
        var data = new {
            Title = HVM.Title.Where(o => o.Language.ID.Equals(id)).First(),
        };
        return Json(new { success = true });
    }

The problem should be located somewhere in the script, the ChangeLanguage Method doesn't even get executed.

回答1:

From the comments, you want to be able to update labels based on the selected language. In order to do this you will need to use ajax to post the selected language to a controller method that return json and update the DOM. Your view model should be

public SelectList AvailableLanguages { get; set; }
public int SelectedLanguage { get; set; }

and in the controller

public ActionResult YourMethod()
{
  var model = new yourModel();
  model.SelectedLanguage = // set this if you want a default
  var availableLanguages = // get you list of languages
  model.AvailableLanguages = new SelectList(availableLanguages, "ID", "LanguageText")
  return View(model);
}

View

@Html.DropDownListFor(m => m.SelectedLanguage, Model.AvailableLanguages)

<script>
  var url = '@Url.Action("GetLanguageLabels", "yourControllerName")';
  $('#SelectedLanguage').change() {
    $.getJSON(url, { ID: $(this).val() }, function(response) {
      // Note you will need to give your labels an id attribute
      $('#Label1').text(response.Label1);
      $('#Label2').text(response.Label2);
    })
  });
</script>

And the method to get the labels based on the selected language

public JsonResult GetLanguageLabels(int ID)
{
  // Build a object of label values based on the selected language ID
  var data = new
  {
    Label1 = someValue,
    Label2 = anotherValue,
    ....
  };
  return Json(data, JsonRequestBehavior.AllowGet);
}

Side note: Some issues with your current code. (1) Your models have fields only, not properties (no get/set) so nothing would be bound on post back. (2) You cannot bind a html control to a complex object (only an value type, or in the case of <select multiple>, an array of value types).



回答2:

You would make sure the elements are in a form and just and the name of the function after the onchange...

@onchange="submitdata();"

Then you would add the script.

function submitdata()
{
  $('form').submit();
}

For a more "MVC" approach you would start with a strongly typed view using a model.

@model My.Path.To.Model

You would also wrap the form data on your razor page with...

using (@Html.BeginForm("myMethod", "Home", FormMethod.Post)){
     //form and inputs here, ect
     <form method="POST" action="" >
         //properties bound to inputs to change your model, or html helpers like display for...
         <input type="Submit" name="Submit" value="Submit"/>
     </form>
}

You would then pass the model as a parameter in the Controller action, this is called on the submit of the form:

[HttpPost]
 public FileStreamResult myMethod(Model model)
 {
     string str = model.imapropertyonthemodel;

 }

If you are new to MVC I would recommend starting with the basics from W3 schools, or if you have pluralsight, there are some great tutorials there.