Comment mettre à jour la propriété sous-jacente ViewModel lors de la suppression d'une photo à l'aide d'un Ajax.ActionLink?
-
27-10-2019 - |
Question
Ma situation est la suivante:
J'ai cette ViewModel:
public class RealtyViewModel
{
public RealtyViewModel()
{
Realty = new Realty();
Photos = new Collection<File>();
}
public Realty Realty { get; set; }
public Collection<File> Photos { get; set; }
}
Je passe cette RealtyViewModel
à mon avis de Edit.cshtml
. A l'intérieur de la vue Modifier j'appelle une vue partielle Photos.cshtml
. La vue partielle Photos utilise également le même @model RealtyViewModel
.
Maintenant, à l'intérieur de la vue partielle Photos.cshtml
je fais une demande d'AJAX pour supprimer une photo:
@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})
Je lance ce code:
[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();
}
Le problème est: mon realtyViewModel
actuel que je suis passé à la vue Modifier référence encore les photos que j'ai supprimé à l'aide des appels AJAX. Ensuite, lorsque je tente de sauvegarder un modèle mis à jour, il enregistre tout nouveau tenant les anciennes références aux photos je viens de supprimer.
Comment puis-je mettre à jour mon modèle (supprimer les photos supprimées de [model.Realty.Photos
]) afin qu'il reflète l'état actuel de mon point de vue Edition?
Note: maintenant il travaille parce que je utilise l'objet Session
pour stocker les Ids de photos supprimées, mais pas la façon dont je pense qu'il devrait être. Il doit y avoir une belle solution à ce qui ne vient pas venir mon esprit ...
Une belle solution serait: après une suppression de succès, l'appel Ajax doit retourner la photo supprimé Id afin que je puisse le retirer de [model.Realty.Photos
]. Puis, quand j'ai essayé d'enregistrer un immobilier édité, il reflète les changements correctement.
La solution
Après une discussion sur le chat il semble que vous ont des champs cachés dans votre DOM que vous devez supprimer:
@for (int i = 0; i < Model.Realty.Photos.Count(); i++)
{
@Html.HiddenFor(
m => m.Realty.Photos[i],
new { data_photoid = Model.Realty.Photos[i] }
)
}
Maintenant, vous pouvez avoir votre action du contrôleur renvoie l'ID de la photo qui doit être supprimé à l'aide JSON par exemple au lieu d'un résultat vide:
[HttpDelete]
public ActionResult DeletePhoto(string realtyId, string photoId)
{
...
return Json(new { photoId = photoId });
}
et sur le client:
function deletePhotoFromPage(result) {
...
$(':hidden[data-photoid="' + result.photoId + '"]').remove();
}
et vous devez utiliser l'option OnSuccess
au lieu de OnComplete
dans les options de lien Ajax:
OnSuccess = "deletePhotoFromPage"
au lieu de:
OnComplete = string.Format("deletePhotoFromPage('{0}')", Model.Photos[i].Id),
OnComplete
pourrait l'être même en cas d'erreur.