ASP.NET MVC, плагин архитектуры и коллизии идентификаторов - PullRequest
4 голосов
/ 16 июня 2009

Итак, я рассказывал о ASP.NET MVC другу, который собирается начать разработку нового пользовательского интерфейса ....

Он спросил меня, можете ли вы решить следующую проблему с ASP.NET MVC:

Представьте себе веб-приложение, которое поддерживает плагины. В текущем приложении ASP.NET WebForms разработчик плагинов предоставляет пользовательский контроль и некоторые JQuery. Идентификаторы элементов управления уникальны, так что JQuery всегда может выбрать правильные элементы DOM и чтобы код позади мог обрабатывать правильные коллекции элементов управления.

Я предположил, что в MVC, поскольку у нас может быть любое количество форм ... каждый плагин может быть реализован как частичное представление.

Каждый частичный вид будет заключен в свою собственную форму, поэтому соответствующее действие контроллера и, следовательно, получит только данные формы, определенные в частичном видении - поэтому с этой точки зрения мы не заботимся о конфликтах идентификаторов DOM.

Однако HTML-код был бы недействительным, если бы произошла коллизия ID, и, следовательно, JQuery, написанный разработчиком плагина, мог завершиться ошибкой!

Я не уверен, как мы могли бы обойти это ...

Мне не нравится идея синтаксического анализа partView на наличие коллизий при добавлении плагина, и мне не нравится идея ограничения идентификаторов, к которым имеет доступ разработчик плагина.

Может быть, идентификаторы могут быть дополнены префиксом во время выполнения, и связующим элементам модели может быть предоставлен этот префикс?

1 Ответ

2 голосов
/ 16 июня 2009

Вы можете просто обернуть содержимое плагина в элемент DIV или FORM и присвоить этому уникальный идентификатор на странице. Затем просто используйте jQuery для выбора только тех элементов, которые находятся внутри этого «родительского» элемента DIV или FORM.

Возможно, вы могли бы автоматически сгенерировать GUID для использования в качестве уникального идентификатора во время выполнения, но это потребует определенных усилий со стороны человека, пишущего плагин. Хотя, возможно, вы могли бы спроектировать его таким образом, чтобы он автоматически генерировал «родительский» DIV и ID, тогда вы могли бы просто получить доступ к идентификатору в представлении как свойству плагина.

Просто некоторые мысли, я еще не создал подобную систему на основе плагинов ASP.NET MVC, но она не кажется слишком сложной.

Вот пример PartialView, который использует собственный базовый класс ViewUserControl:

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>");
            }
        }
    } 
}

Затем, чтобы разместить представление на странице, вы можете использовать метод «Html.RenderPartial», как обычно, плюс вы можете разместить столько страниц на странице, сколько захотите, и все они будут работать как положено.

<%Html.RenderPartial("ViewUserControl1"); %>
<%Html.RenderPartial("ViewUserControl1"); %>
<%Html.RenderPartial("ViewUserControl1"); %>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...