2012-05-23 44 views
10

Soy nuevo en MVC3, tengo varios modelos como BussinessDetails, ContactPerson, ServiceArea, Address y muchos más modelos. Tengo una página de vista única donde las páginas de vista compartida como Contacts, BusinessDetails, Address, ServiceArea etc. están todas en pestañas. Ellos tienen sus propios modelos.Cómo editar varios modelos en una sola Vista Razor

Mi problema es que cómo editar varios modelos en una misma página de vista de edición. Antes de enviar esta publicación, tomo la ayuda del ejemplo MVC3 "Tienda de música" pero solo hay un modelo ALBUM y dan operación de edición para un modelo si hay uno o más modelos que debo editar en la misma página de vista.

Ya he hecho una clase de especificación de negocio principal. Esto es de MVC "tienda de música"

public ActionResult Edit(int id) { 
    Album album = db.Albums.Find(id); 
    ViewBag.GenreId = new SelectList(db.Genres, "GenreId", "Name", album.GenreId); 
    ViewBag.ArtistId = new SelectList(db.Artists, "ArtistId", "Name", album.ArtistId); 
    return View(album); 
}               

[HttpPost] 
public ActionResult Edit(Album album) { 
    if (ModelState.IsValid) { 
     db.Entry(album).State = EntityState.Modified; 
     db.SaveChanges(); 
     return RedirectToAction("Index"); 
    } 

    ViewBag.GenreId = new SelectList(db.Genres, "GenreId", "Name", album.GenreId); 
    ViewBag.ArtistId = new SelectList(db.Artists, "ArtistId", "Name", album.ArtistId); 
    return View(album); 
}                 

En HTTP POST sólo existe en el modelo ALBUM si hay más modelos como soy realizar la operación de edición en varios modelos y punto de vista?

Respuesta

8

Tendrá que crear un modelo de vista que contenga los dos tipos que necesita.Algo como esto (suponiendo que está editando tanto un álbum y un artista):

public class MyModel 
{ 
    public Album Album { get; set; } 
    public Artist Artist { get; set; } 
    public SelectList Genres { get; set; } 
    public SelectList Artists{ get; set; } 
} 

A continuación, cambiar la vista para utilizar el nuevo modelo de este modo:

@model MyModel 

A continuación, cambiar la forma de llegar a ser algo así como:

public ActionResult Edit(int id) 
{ 
    var model = new MyModel(); 
    model.Album = db.Albums.Find(id); 
    model.Artist = yourArtist; //whatever you want it to be 
    model.Genres = new SelectList(db.Genres, "GenreId", "Name", model.Album.GenreId); 
    model.Artists = new SelectList(db.Artists, "ArtistId", "Name", model.Album.ArtistId); 

    return View(model); 
} 

a continuación, cambiar su método post para tomar el tipo MyModel:

[HttpPost] 
public ActionResult Edit(MyModel model) { 

    if (ModelState.IsValid) { 
    //save your items here 

     db.SaveChanges(); 

     return RedirectToAction("Index"); 
    } 

    model.Genres = new SelectList(db.Genres, "GenreId", "Name", model.Album.GenreId); 
    model.Artists = new SelectList(db.Artists, "ArtistId", "Name", model.Album.ArtistId); 

    return View(album); 
}  

Asumiendo que su punto de vista tiene algo parecido (envuelto en un formulario con un botón de enviar, por supuesto):

@Html.EditorFor(m => m.Artist.Name) //do this for all Artist Fields 
@Html.EditorFor(m =? m.Album.Name) //do this for all Album Fields 

//the following two show you how to wire up your dropdowns: 
@Html.DropDownListFor(m => m.Album.ArtistId, Model.Artists) 
@Html.DropDownListFor(m => m.Album.GenreId, Model.Genres) 
+1

lo que estoy escribiendo después si (ModelState. IsValid) { para editar un modelo en particular. – user1196392

+0

@ user1196392 ¿No puedes llamar algo como 'Guardar' en tus clases de datos? Algo así como 'modelo.Album.Save();' para cada tipo en el modelo. – mattytommo

20

Es necesario incluir los otros ViewModels en un principal CompositeModel al igual que

public class CompositeModel { 
    public Album AlbumModel { get; set; } 
    public Another AnotherModel { get; set; } 
    public Other EvenMore { get; set; } 
} 

Envíelo a su vista como así

public ActionResult Index() { 
    var compositeModel = new CompositeModel(); 
    compositeModel.Album = new AlbumModel(); 
    compositeModel.OtherModel = new AnotherModel(); 
    compositeModel.EvenMore = new Other();   
    return View(compositeModel) 
} 

Modifique su vista para tomar el nuevo tipo de modelo

@model CompositeModel 

hacer referencia a propiedades de los submodelos puede utilizar la sintaxis como esta

@Html.TextBoxFor(model => model.Album.ArtistName) 

o puede crear una vista en la carpeta EditorTemplates que tiene un sub-modelo como AlbumModel y utilizar EditorFor como esto

@Html.EditorFor(model => model.Album) 

La plantilla se vería algo como esto

@model AlbumModel 

@Html.TextBoxFor(model => model.AlbumName) 
@Html.TextBoxFor(model => model.YearReleased) 
@Html.TextBoxFor(model => model.ArtistName) 

Ahora solo publique CompositeModel de vuelta a su controlador y luego guarde todos los submodelos y ahora Bob es su tío!

[HttpPost] 
public ActionResult Index(CompositModel model) { 
    // save all models 
    // model.Album has all the AlbumModel properties 
    // model.Another has the AnotherModel properties 
    // model.EvenMore has the properties of Other 
} 
+0

esta solución no funciona para mí – user1196392

+1

Esto fue solo un seudocódigo, que no debe tomarse literalmente, tendrá que averiguar cómo corregirlo o publicar el nuevo código que está intentando para que podamos ayudarlo. Mantenga el ciclo de retroalimentación en marcha :-) –

Cuestiones relacionadas