2012-02-27 2 views
3

Je viens d'un fond d'application plus WPF et je suis habitué à des liaisons et autres. Sauter dans des sites Web peut alors venir avec ses problèmes car ils travaillent beaucoup plus différemment.Ajax simple dans asp.net MVC 3, mettre à jour le modèle et la partie du rerender

J'essaie de faire une action simple Ajax mais je ne sais pas par où commencer. Fondamentalement, je veux faire une liste déroulante qui modifie une propriété sur le modèle et rend à nouveau cette partie de la page. Peut-être que c'est trop une manière de WPF pour faire ceci afin que mon modèle puisse être tordu pour la chose qu'il est censé faire.

Voici ce que je suis déjà:

public class TheViewModel 
{ 
    private IEnumerable<TheData> _data; 

    public TheViewModel(IEnumerable<TheData> data) 
    { 
     _data = data; 
     Year = 2012; 
    } 

    public int Year { get; set; } 

    public ICollection<TheData> Data 
    { 
     get 
     { 
      return _data.Where(d => d.Year == this.Year).ToList(); 
     } 
    } 

    public IEnumerable<SelectListItem> YearList 
    { 
     // lists the available years 
    } 
} 

public class TheData 
{ 
    public int Year { get; set; } 
    //Some more info I want to represent in Table 
} 

Et le rasoir:

@using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId = "thetable" })) 
{ 
     @Html.DropDownListFor(model => model.Year, Model.YearList, new { AutoPostBack = "true"}) 
     <input type="submit" name="name" value="Submit" /> 
} 


<table id="thetable"> 
    <thead> 
     //some headers 
    </thead> 
    <tbody> 
    @foreach (var item in Model.Data) 
    { 
     //row for each data 
    } 
    </tbody> 
</table> 

Comme vous pouvez le voir, je suis l'espoir de la propriété Année être mis à jour et un nouvel appel à être fait pour la propriété de données qui entraînerait de nouvelles informations. Cette information sera affichée en thetable Tableau

Répondre

10

Voici un exemple complet.

Modèle:

public class MyViewModel 
{ 
    public int Year { get; set; } 
    public IEnumerable<SelectListItem> Years 
    { 
     get 
     { 
      return Enumerable.Range(1980, 40).Select(x => new SelectListItem 
      { 
       Value = x.ToString(), 
       Text = x.ToString() 
      }); 
     } 
    } 

    public IList<TheData> Data { get; set; } 
} 

public class TheData 
{ 
    public int Year { get; set; } 
    public string Foo { get; set; } 
    public string Bar { get; set; } 
} 

Controller:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     var model = new MyViewModel(); 
     return View(model); 
    } 

    [HttpPost] 
    public ActionResult Index(int year) 
    { 
     var model = new[] 
     { 
      new TheData { Year = year, Foo = "foo 1", Bar = "bar 1" }, 
      new TheData { Year = year, Foo = "foo 2", Bar = "bar 2" }, 
      new TheData { Year = year, Foo = "foo 3", Bar = "bar 3" }, 
     }; 
     return PartialView("_data", model); 
    } 
} 

Index.cshtml Vue:

@model MyViewModel 

<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script> 
<script type="text/javascript"> 
    $(function() { 
     $('#yearsddl').change(function() { 
      $(this).closest('form').trigger('submit'); 
     }); 
    }); 
</script> 

@using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId = "data" })) 
{ 
    @Html.DropDownListFor(x => x.Year, Model.Years, new { id = "yearsddl" }) 
} 

<table> 
    <thead> 
     <tr> 
      <th>Year</th> 
      <th>Foo</th> 
      <th>Bar</th> 
     </tr> 
    </thead> 
    <tbody id="data"> 
     @Html.Partial("_data", Model.Data ?? Enumerable.Empty<TheData>()) 
    </tbody> 
</table> 

L'inclusion de script jquery.unobtrusive-ajax.js devrait être déplacé hors de la vue d'index dans la mise en page par exemple et le js personnalisé qui souscrit à l'événement de changement de la liste déroulante doit être déplacée dans un fichier js distinct et incluse dans la mise en page. Je les ai juste mis ici pour illustrer un exemple complet de ce qui est nécessaire pour que la vue fonctionne.

_Data.cshtml partielle:

@model IList<TheData> 

@for (int i = 0; i < Model.Count; i++) 
{ 
    <tr> 
     <td>@Html.DisplayFor(x => x[i].Year)</td> 
     <td>@Html.DisplayFor(x => x[i].Foo)</td> 
     <td>@Html.DisplayFor(x => x[i].Bar)</td> 
    </tr> 
} 
+0

Ok merci, voilà ce que je avais besoin. À partir de votre solution, j'ai décidé de séparer en 2 modèles avec des informations en dehors de la mise à jour dans un et la mise à jour dans un autre. Problème il y a le réglage des données par défaut. Html.Partial signifierait que je devrais inclure l'autre viewmodel avec le paramètre par défaut dans l'autre. J'espérais donc pouvoir simplement appeler Html.Action à la place, mais je ne sais pas trop comment l'appeler au lieu de l'obtenir. –

+0

Eh bien un autre problème est que DropDownList est forcé d'être à l'intérieur de partialView en raison du style. Ça marche la première fois mais pas encore. –

+0

@ IngóVals, dans ce cas vous devriez utiliser '.delegate' ou' .on (dans jQuery 1.7+) au lieu de '.change' pour vous abonner à l'événement change de la liste déroulante si ce ddl est ajouté par la suite dans le DOM en utilisant AJAX par exemple. –

Questions connexes