2009-06-16 8 views
4

So habe ich an einen Freund lyrisch über eine ASP.NET MVC wurde Wachsen, die im Begriff ist, die Entwicklung einer neuen Benutzeroberfläche zu starten ....ASP.NET MVC, eine Plugin-Architektur und id Kollisionen

Er fragte Wenn Sie das folgende Problem mit ASP.NET MVC lösen könnten:

Stellen Sie sich eine Web-App vor, die Plugins unterstützt. In der aktuellen ASP.NET WebForms App stellt der Pluggin-Entwickler eine Benutzersteuerung und einige JQuery-Funktionen bereit. Die IDs der Steuerelemente sind eindeutig, sodass JQuery immer die richtigen DOM-Elemente auswählen kann und der dahinter stehende Code die richtigen Steuerelementauflistungen verarbeiten kann.

Ich schlug vor, dass in MVC, da wir eine beliebige Anzahl von Formen haben können ... jedes Plugin könnte als eine Teilansicht implementiert werden.

Jede partialView würde von ihrer eigenen Form umschlossen werden, also die relevante Controller Action und würde daher nur die in der partialView definierten Formulardaten erhalten - aus diesem Blickwinkel sind uns DOM ID Kollisionen egal.

Allerdings wäre der HTML-Code ungültig, wenn eine ID-Kollision aufgetreten wäre und daher JQuery, geschrieben vom Plugin-Entwickler, fehlschlagen könnte!

Ich bin nicht sicher, wie wir herumkommen könnte ...

Ich mag die Idee nicht für Kollisionen die PartialView Parsen, wenn das Plugin hinzugefügt wird und ich nicht wie die Idee, die IDs der Einschränkung, dass die Plugin-Entwickler hat Zugriff auf.

Vielleicht könnten die IDs zur Laufzeit mit einem Präfix ergänzt werden, und die Modellbinder könnten mit diesem Präfix versehen werden?

Antwort

2

Sie könnten den Inhalt des Plugins einfach in ein DIV- oder FORM-Element einfügen und diesem eine eindeutige ID auf der Seite geben. Verwenden Sie jQuery dann nur, um Elemente auszuwählen, die sich innerhalb dieses "übergeordneten" DIV- oder FORM-Elements befinden.

Sie könnten wahrscheinlich eine GUID erstellen, die zur Laufzeit als eindeutige ID verwendet wird. Dies würde jedoch einige Anstrengungen seitens der Person erfordern, die das Plugin schreibt. Obwohl Sie es wahrscheinlich so gestalten könnten, dass es automatisch das "Eltern" -DIV und die ID generiert, können Sie einfach auf die ID innerhalb der Ansicht als Eigenschaft des Plugins zugreifen.

Nur ein paar Gedanken, ich habe noch kein ASP.NET MVC-Plugin-System wie dieses gebaut, aber es scheint nicht zu schwierig.

Hier ist ein Beispiel für eine PartialView, die eine benutzerdefinierte Viewusercontrol-Basisklasse verwendet:

ViewUserControl1.ascx:

<%@ Control Language="C#" Inherits="MvcPluginPartialView.PluginViewUserControl" %> 
<input class="txtText" type="text" value="<%=this.ID %>" /> 
<input class="txtButton" type="button" value="Show Alert" /> 
<script type="text/javascript"> 
    jQuery(function() { 
     // This is the Unique ID of this Plugin on the Page 
     var pluginID = "<%=this.ID %>"; 

     // Attach the OnClick event of the Button 
     $("#" + pluginID + " .txtButton").click(function() { 
      // Display the content of the TextBox in an Alert dialog. 
      alert($("#" + pluginID + " .txtText").val()); 
     }); 
    }); 
</script> 

MvcPluginPartialView.PluginViewUserControl:

namespace MvcPluginPartialView 
{ 
    public class PluginViewUserControl : ViewUserControl 
    { 
     public PluginViewUserControl() 
     { 
      this.ID = "p" + Guid.NewGuid().ToString().Replace("-", ""); 
     } 

     public override void RenderView(ViewContext viewContext) 
     { 
      viewContext.HttpContext.Response.Cache.SetExpires(DateTime.Now); 
      ViewUserControlContainerPage containerPage = new ViewUserControlContainerPage(this); 
      //this.ID = Guid.NewGuid().ToString(); 
      RenderViewAndRestoreContentType(containerPage, viewContext); 
     } 

     internal static void RenderViewAndRestoreContentType(ViewPage containerPage, ViewContext viewContext) 
     { 
      string contentType = viewContext.HttpContext.Response.ContentType; 
      containerPage.RenderView(viewContext); 
      viewContext.HttpContext.Response.ContentType = contentType; 
     } 

     private sealed class ViewUserControlContainerPage : ViewPage 
     { 
      public ViewUserControlContainerPage(ViewUserControl userControl) 
      { 
       this.Controls.Add(userControl); 
      } 

      protected override void Render(System.Web.UI.HtmlTextWriter writer) 
      { 
       writer.Write("<div id='" + this.Controls[0].ID + "'>"); 

       base.Render(writer); 

       writer.Write("</div>"); 
      } 
     } 
    } 
} 

dann auf die Ansicht zu platzieren Auf der Seite können Sie die "Html.RenderPartial" -Methode wie gewohnt verwenden, und Sie können so viele von ihnen auf der Seite platzieren, wie Sie möchten, und sie werden alle als ex funktionieren erkannt.

+2

Egal welche Lösung, es sollte für den Plugin-Entwickler transparent sein - sie sollten sich nicht um die ID-Generierung kümmern. – iasksillyquestions

+0

Ok.Ich habe nur einen Beispielcode hinzugefügt, der zeigt, wie man das macht, und der Plugin-Entwickler muss sich nicht darum kümmern, wie die eindeutige ID gesetzt wird, sie müssen ihn nur benutzen, um von jQuery auf das Steuerelement zuzugreifen. –