2011-01-17 3 views
1

Ich benutze asp.net mvc ajax.asp.net mvc Ajax.BeginForm Klon

Die Teilansicht wird mit Ajax.BeginForm (nur ein Beispiel):

<div id="divPlaceholder"> 
<% using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId = "divPlaceholder" })) { %> 
    ... asp.net mvc controls and validation messages 
    <input type="submit" value="Save" /> 
<% } %> 
</div> 

Nach der Aktualisierung, wenn die Validierung fehlschlägt, die html ist:

<div id="divPlaceholder"> 
    <div id="divPlaceholder"> 
    ...form 
    </div> 
</div> 

Ich mag es nicht, dass die returned html wird eingefügt, stattdessen sollte das ursprüngliche div ersetzt werden.

Wahrscheinlich auf POST sollte ich nicht <div> um Form in Teilansicht rendern oder das Div ohne ID rendern.

Was kann ich sonst in dieser Situation tun?

Ich dachte, dass ich vielleicht einen Helfer schreiben sollte, etwas wie Ajax.DivBeginForm, das Formular innerhalb von div auf GET rendert und das div auf POST versteckt.

Kann jemand einen guten Rat geben, wie man solchen Helfer schreibt (Ajax.DivBeginForm)?

Ich würde es gerne mit der Verwendung von Keyword arbeiten:

<% using (Ajax.DivBeginForm(new AjaxOptions { UpdateTargetId = "myId" })) { ... }%> 

Antwort

0

können Sie behandeln einreichen selbst bilden:

<div id="divPlaceholder"> 
<% using (Html.BeginForm("action", "controller", FormMethod.Post, new { id = "submitForm"})) { %> 
    ... asp.net mvc controls and validation messages 
    <input type="submit" value="Save" /> 
<% } %> 
</div> 

und einige Javascript wie schreiben:

$('#submitForm').submit(function() { 
    $.post('post-to-this-url', 
     data: { foo: formvalue1, bar: formvalue2}, 
     function(data) { 
     // update html here 
    }); 
    return false; 
}) 
+0

Ja, das ist ein guter Artikel, der es erklärt - http://jvance.com/blog/2010/02/20/MakingAnAjaxFormWithJQueryInASPdotNETMVC.xhtml. Aber ich möchte nicht jedesmal zusätzliches Javascript schreiben. –

1

Meine Lösung. Bitte kommentieren Sie, wenn etwas nicht stimmt.

public class DivMvcForm : MvcForm 
{ 
    private bool _disposed; 
    private MvcForm mvcForm; 
    private ViewContext viewContext; 

    public DivMvcForm(MvcForm mvcForm, ViewContext viewContext) : base(viewContext) 
    { 
     this.mvcForm = mvcForm; 
     this.viewContext = viewContext; 
    } 

    protected override void Dispose(bool disposing) 
    { 
     if (!_disposed) 
     { 
      _disposed = true; 

      mvcForm.EndForm(); 

      viewContext.Writer.Write("</div>"); 
     } 
    } 
} 

Helper

public static class AjaxHelperExtensions 
{ 
    public static MvcForm DivBeginForm(this AjaxHelper ajaxHelper, AjaxOptions ajaxOptions) 
    { 
     var tagBuilder = new TagBuilder("div"); 

     if (ajaxHelper.ViewContext.HttpContext.Request.RequestType == "GET" 
      && string.IsNullOrWhiteSpace(ajaxOptions.UpdateTargetId) != true) 
     { 
      tagBuilder.MergeAttribute("id", ajaxOptions.UpdateTargetId); 
     } 

     ajaxHelper.ViewContext.Writer.Write(tagBuilder.ToString(TagRenderMode.StartTag)); 

     var theForm = ajaxHelper.BeginForm(ajaxOptions); 

     return new DivMvcForm(theForm, ajaxHelper.ViewContext); 
    } 
} 

Und wie funktioniert es

<% using (Ajax.DivBeginForm(new AjaxOptions { UpdateTargetId = "divPlaceholder" })) { %> 
    ... controls 
<% } %> 

Ergebnis - wenn Model ungültig die Teilansicht kehrt div ohne id ist.

+0

das ist die richtige Antwort. – splattne

2

Ich nehme hier einen etwas anderen Ansatz, anstatt die ursprüngliche Lösung zum Laufen zu bringen, würde ich empfehlen, das Muster zu verwenden, das normalerweise in diesem Szenario verwendet wird, und keinen Helfer zu verwenden. Ich weiß, das ist ein bisschen später als der ursprüngliche Beitrag, aber für die zukünftige Verwendung von jedermann:)

Wenn Ihre Teilansicht ein Formular hat, dann werden Sie weiterhin buchen und ein Formular in einem Formular in einem Formular in einer Form usw., so dass Sie Ihre Eltern haben wollen enthalten Begin, die div und

 
using (Ajax.BeginForm("Index", "ProjectManager", new AjaxOptions() .... 
<div id="divPlaceholder"> 
    Html.RenderPartial(....) 
</div> 

renderPartial Wenn Sie diese Logik kapseln möchte sagen wir, eine „Ordnung“ Teilansicht, die auf einem Kundenbildschirm angezeigt wird, dann hast du zwei Möglichkeiten. 1. Fügen Sie das BeginForm-Objekt in die übergeordnete Kundenansicht ein (wodurch die Wiederverwendbarkeit von Code reduziert wird, da jede Ansicht, die die Teilansicht "Auftrag" enthalten soll, die Ajax-Verdrahtung enthalten muss. 2. Sie haben zwei Teilansichten für die Bestellung OrderIndex.ascx (oder cshtml wenn Rasiermesser) und eins ist OrderIndexDetail.ascx (oder die von Ihnen gewählte Namenskonvention)

OrderIndex enthält Ihre Ajax.beginform und OrderIndexDetail hat keine Form, nur die Teilansichtsdetails.

Option 2 ist mehr Code (ok, wörtlich etwa 30 Sekunden mehr Code zum Verschieben der ajax.beginform in eine andere Ansicht), erhöht aber die Wiederverwendbarkeit des Codes.