Oui, il est possible
que vous avez une forme et vous avez la collection nommée « Livres ». Si vous souhaitez ajouter un nouveau livre par programme, vous pouvez utiliser jQuery et ajax. Fist vous avez besoin de cours d'aide.
Les classes suivantes vous aident à créer un élément de livre unique à ajouter à la collection de livres dans votre vue. Comme vous le savez tous les domaines doit avoir le préfixe unique, donc van liant modèle distinction entre les éléments de formulaire
public static class HtmlClientSideValidationExtensions
{
public static IDisposable BeginAjaxContentValidation(this HtmlHelper html, string formId)
{
MvcForm mvcForm = null;
if (html.ViewContext.FormContext == null)
{
html.EnableClientValidation();
mvcForm = new MvcForm(html.ViewContext);
html.ViewContext.FormContext.FormId = formId;
}
return new AjaxContentValidation(html.ViewContext, mvcForm);
}
private class AjaxContentValidation : IDisposable
{
private readonly MvcForm _mvcForm;
private readonly ViewContext _viewContext;
public AjaxContentValidation(ViewContext viewContext, MvcForm mvcForm)
{
_viewContext = viewContext;
_mvcForm = mvcForm;
}
public void Dispose()
{
if (_mvcForm != null)
{
_viewContext.OutputClientValidation();
_viewContext.FormContext = null;
}
}
}
}
public static class CollectionValidation
{
private const string idsToReuseKey = "__htmlPrefixScopeExtensions_IdsToReuse_";
public static IDisposable BeginCollectionItem(this HtmlHelper html, string collectionName)
{
var idsToReuse = GetIdsToReuse(html.ViewContext.HttpContext, collectionName);
string itemIndex = idsToReuse.Count > 0 ? idsToReuse.Dequeue() : Guid.NewGuid().ToString();
// autocomplete="off" is needed to work around a very annoying Chrome behaviour whereby it reuses old values after the user clicks "Back", which causes the xyz.index and xyz[...] values to get out of sync.
html.ViewContext.Writer.WriteLine(string.Format("<input type=\"hidden\" name=\"{0}.index\" autocomplete=\"off\" value=\"{1}\" />", collectionName, html.Encode(itemIndex)));
return BeginHtmlFieldPrefixScope(html, string.Format("{0}[{1}]", collectionName, itemIndex));
}
public static IDisposable BeginHtmlFieldPrefixScope(this HtmlHelper html, string htmlFieldPrefix)
{
return new HtmlFieldPrefixScope(html.ViewData.TemplateInfo, htmlFieldPrefix);
}
private static Queue<string> GetIdsToReuse(HttpContextBase httpContext, string collectionName)
{
// We need to use the same sequence of IDs following a server-side validation failure,
// otherwise the framework won't render the validation error messages next to each item.
string key = idsToReuseKey + collectionName;
var queue = (Queue<string>)httpContext.Items[key];
if (queue == null)
{
httpContext.Items[key] = queue = new Queue<string>();
var previouslyUsedIds = httpContext.Request[collectionName + ".index"];
if (!string.IsNullOrEmpty(previouslyUsedIds))
foreach (string previouslyUsedId in previouslyUsedIds.Split(','))
queue.Enqueue(previouslyUsedId);
}
return queue;
}
private class HtmlFieldPrefixScope : IDisposable
{
private readonly TemplateInfo templateInfo;
private readonly string previousHtmlFieldPrefix;
public HtmlFieldPrefixScope(TemplateInfo templateInfo, string htmlFieldPrefix)
{
this.templateInfo = templateInfo;
previousHtmlFieldPrefix = templateInfo.HtmlFieldPrefix;
templateInfo.HtmlFieldPrefix = htmlFieldPrefix;
}
public void Dispose()
{
templateInfo.HtmlFieldPrefix = previousHtmlFieldPrefix;
}
}
}
Ensuite, nous supposons que vous avez une vue partielle pour ajouter des livres comme celui-ci:
@model Models.Book
@using (Html.BeginAjaxContentValidation("form"))
{
using (Html.BeginCollectionItem("Books"))
{
<div class="fieldcontanier">
@Html.LabelFor(model => model.Title)
@Html.EditorFor(model => model.Title)
@Html.ValidationMessageFor(model => model.Title)
</div>
<div class="fieldcontanier">
@Html.LabelFor(model => model.Author)
@Html.EditorFor(model => model.Author)
@Html.ValidationMessageFor(model => model.Author)
</div>
...
}
}
et supposer qu'il est un lien « ajouter un nouveau livre » sous forme que vous avez défini événement suivant pour que jQuery:
$('a ').click(function (e) {
e.preventDefault();
$.ajax({
url: '@Url.Action("NewBook")',
type: 'GET',
success: function (context) {
$('#books').append(context);
$("form").removeData("validator");
$("form").removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse("form");
}
});
});
dans le code ci-dessus, tout d'abord vous demandez à l'action appelée NewBook, qui renvoie une vue partielle, je l'ai mentionné plus tôt, puis chargé après d'autres livres dans la page, puis pour la validation discrète à appliquer, nous utilisons les dernières lignes d'arbres.
vous voulez dire que vous ne voulez pas enregistrer cha nges jusqu'à ce que toute la liste soit affichée? Pourquoi est ce que tu veux faire ça? – ataravati
Je prévois d'utiliser les valeurs pour enregistrer dans la base de données sur la publication, donc je ne veux pas sauvegarder les valeurs jusqu'à ce qu'elles soient sauvegardées au cas où elles feraient une erreur et fermeraient le navigateur. Ou ai-je oublié quelque chose? – heilch
Eh bien, vous leur fournissez la liste, et ils peuvent modifier/supprimer chaque élément de la liste. Vous n'avez pas à renvoyer toute la collection au serveur, seulement celle qui est modifiée. – ataravati