¿Cómo actualizar la propiedad ViewModel subyacente al eliminar una foto usando un Ajax.ActionLink?
-
27-10-2019 - |
Pregunta
Mi situación es esta:
tengo esto ViewModel:
public class RealtyViewModel
{
public RealtyViewModel()
{
Realty = new Realty();
Photos = new Collection<File>();
}
public Realty Realty { get; set; }
public Collection<File> Photos { get; set; }
}
PASO ESTO RealtyViewModel
para mi Edit.cshtml
vista. Dentro de la vista de edición, llamo a un Photos.cshtml
vista parcial. La vista parcial de las fotos también usa lo mismo @model RealtyViewModel
.
Ahora, dentro del Photos.cshtml
Vista parcial Hago una solicitud de AJAX para eliminar una foto:
@Ajax.ImageActionLink
(@Url.Content(Model.Photos[i].Path), @Localization.Delete, "640", "480",
"DeletePhoto", new {realtyId = Model.Realty.Id, photoId = Model.Photos[i].Id},
new AjaxOptions()
{
Confirm = @Localization.DeleteConfirmation,
HttpMethod = HttpVerbs.Post.ToString(),
OnComplete = string.Format("deletePhotoFromPage('{0}')",
Model.Photos[i].Id),
OnSuccess = "LoadCycle",
UpdateTargetId = "myDiv",
InsertionMode = InsertionMode.Replace
}, new {data_photoId = Model.Photos[i].Id})
Ejecuto este código:
[HttpDelete]
public ActionResult DeletePhoto(string realtyId, string photoId)
{
Realty realty = DocumentSession.Load<Realty>(realtyId);
realty.Photos.Remove(photoId);
File photo = DocumentSession.Load<File>(photoId);
// Deletes the file in the database
DocumentSession.Advanced.DatabaseCommands.Delete(photoId, null);
// Deletes the file in the disk
System.IO.File.Delete(Server.MapPath(photo.Path));
return new EmptyResult();
}
El problema es: mi actual realtyViewModel
que pasé a la vista de edición todavía hace referencia a las fotos que he eliminado usando las llamadas AJAX. Luego, cuando trato de guardar un modelo actualizado, guarda todo nuevamente sosteniendo las viejas referencias a las fotos que acabo de eliminar.
¿Cómo puedo actualizar mi modelo (elimine las fotos eliminadas de [ model.Realty.Photos
]) para que refleje el estado actual de mi vista de edición?
Nota: Ahora está funcionando porque estoy usando el Session
Objetes para almacenar las ID de fotos eliminadas, pero no es así, creo que debería ser. Debe haber una hermosa solución a esto que simplemente no me viene a la mente ...
Una hermosa solución sería: después de una eliminación de éxito, la llamada AJAX debería devolver la identificación de foto eliminada para poder eliminarla de [ model.Realty.Photos
] Luego, cuando intenté guardar una Realty editada, reflejaría los cambios correctamente.
Solución
Después de Discusión sobre el chat Parece que tiene campos ocultos en su DOM que necesita eliminar:
@for (int i = 0; i < Model.Realty.Photos.Count(); i++)
{
@Html.HiddenFor(
m => m.Realty.Photos[i],
new { data_photoid = Model.Realty.Photos[i] }
)
}
Ahora podría hacer que su acción del controlador devuelva la identificación de la foto que debe eliminarse usando JSON, por ejemplo, en lugar de un resultado vacío:
[HttpDelete]
public ActionResult DeletePhoto(string realtyId, string photoId)
{
...
return Json(new { photoId = photoId });
}
y en el cliente:
function deletePhotoFromPage(result) {
...
$(':hidden[data-photoid="' + result.photoId + '"]').remove();
}
y también deberías usar el OnSuccess
opción en lugar de OnComplete
En sus opciones de enlace de Ajax:
OnSuccess = "deletePhotoFromPage"
en vez de:
OnComplete = string.Format("deletePhotoFromPage('{0}')", Model.Photos[i].Id),
OnComplete
podría invocarse incluso en caso de error.