Простые ASP.NET MVC CRUD представления открываются / закрываются в диалоговом окне JavaScript UI - PullRequest
10 голосов
/ 04 декабря 2009

У меня есть различные простые представления ASP.NET MVC для операций CRUD, которые прекрасно работают как простая веб-страница. Теперь я буду интегрировать их в сам сайт (в контент) и, например, иметь ссылки типа «Создать новое сообщение», которые будут запускать представление в выбранном клоне Lightbox (пока не знаю, какой именно, например Colorbox или Thickbox, но это не имеет значения).

Чего я хочу добиться, так это чтобы само представление каким-то образом обнаруживало, что оно было открыто в диалоговом окне JavaScript UI, так что действие Form (чаще всего POST с использованием простой кнопки Submit) будет отображаться с логикой, которая закрывает UI диалоговое окно после выполнения действия.

Способ работы представлений теперь - POST / Redirect / GET. Представление должно по-прежнему поддерживать этот простой шаблон при открытии непосредственно через URL в веб-браузере, но должно отображать некоторую дополнительную логику при открытии через диалог JavaScript.

Надеюсь, вы понимаете мой вопрос. Любая помощь приветствуется

Ответы [ 2 ]

11 голосов
/ 04 декабря 2009

Вам повезло, я сделал это!

Итак, первое, что вам нужно, это новый ViewEngine для обработки рендеринга страницы без всего того, что обычно мешает вашим модальным окнам. Самый простой способ сделать это - использовать в основном пустую главную страницу для ваших модальных окон. Вы хотите, чтобы логика переключения главной страницы была в стороне и в пользовательском ViewEngine, потому что в противном случае каждый метод контроллера должен иметь if () else () повсеместно, обнаруживающий IsAjaxRequest (). Мне нравится сухой, Сахара сухой.

С помощью этой техники у меня также есть преимущество в том, что я очень изящно деградирую. Мой сайт работает без JavaScript просто отлично. Ссылки в порядке, формы работают, ноль изменений кода для перехода от "модального сайта" к отправке простой старой HTML-формы.

Все, что я сделал, это создал подкласс движка по умолчанию и добавил несколько битов выбора MasterPage:

The View Engine:

public class ModalViewEngine : VirtualPathProviderViewEngine 
{
    public ModalViewEngine()
    {                
     /* {0} = view name or master page name 
      * {1} = controller name      */  

     MasterLocationFormats = new[] {  
         "~/Views/Shared/{0}.master"  
     };  

     ViewLocationFormats = new[] {  
         "~/Views/{1}/{0}.aspx",  
         "~/Views/Shared/{0}.aspx"
     };  

     PartialViewLocationFormats = new[] {  
         "~/Views/{1}/{0}.ascx",               
        }; 
    }

    protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
    {
        throw new NotImplementedException();
    }

    protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
    {

        return new WebFormView(viewPath, masterPath );
    }

    public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
    {
        //you might have to customize this bit
        if (controllerContext.HttpContext.Request.IsAjaxRequest())
            return base.FindView(controllerContext, viewName, "Modal", useCache);

        return base.FindView(controllerContext, viewName, "Site", useCache);
    }

    protected override bool FileExists(ControllerContext controllerContext, string virtualPath)
    {
        return base.FileExists(controllerContext, virtualPath);
    }        
}

Так что моя страница Modal.Master очень проста. Все, что у меня есть, это div-обертка, поэтому я знаю, когда что-то отображается внутри модального окна. Это будет полезно, когда вам нужно выбрать определенные элементы с помощью jquery только тогда, когда они находятся в «модальном режиме».

Modal.Master

<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>
<div id="modalcontent"><asp:ContentPlaceHolder ID="MainContent" runat="server" /></div>

Следующим шагом будет создание вашей формы. Я использую имя свойства по умолчанию = входное имя, чтобы легко связать модель и упростить процесс. Ничего особенного в форме. Я выгляжу так же, как вы бы сделали это нормально. (Обратите внимание, что я использую MVC 2 и EditorFor () в своем коде, но это не должно иметь значения) Вот мой последний HTML:

Вывод HTML

<div id="modalcontent">
    <h2>EditFood</h2>
    <div id="form">
        <form method="post" action="/edit/food?Length=8">
            <input id="CommonName" class="text-box single-line" type="text" value="" name="CommonName"/>
            <input class="button" type="submit" value="Edit Food"/>
        </form>
    </div>
</div>

Помимо очень приятного связывания моделей, вы также можете использовать плагин Jquery.Form , чтобы иметь простые и понятные возможности ajax в вашем приложении с минимальным кодом. Теперь я выбрал ColorBox в качестве скрипта модального окна исключительно потому, что мне нужны прозрачные углы Facebookesque, и мне нравятся точки расширяемости, добавленные автором.

Теперь, когда эти сценарии объединены, вы получите действительно хорошую комбинацию, которая делает эту технику по-настоящему глупой в javascript. Единственный javascript, который я должен был добавить, был (внутри document.ready):

Javascript / Jquery

    $("a.edit").colorbox({ maxWidth: "800px", opacity: 0.4, initialWidth: 50, initialHeight: 50 });

    $().bind('cbox_complete', function () {
        $("#form form").ajaxForm(function () { $.fn.colorbox.close() });
    });

Здесь я говорю ColorBox, чтобы открыть модальное окно для моих ссылок редактирования (Edit Food). Затем с привязкой перейдите к событию complete из colorbox, чтобы соединить ваши элементы ajaxform с обратным вызовом успеха, чтобы сообщить ColorBox закрыть модальное окно. Вот и все.

Этот код был сделан как доказательство концепции, и поэтому движок представления действительно облегчен, и нет проверки или другой стандартной формы. ColorBox и JQuery.Form имеют тонну поддержки расширяемости, поэтому их легко настроить.

Обратите внимание, что все это было сделано в MVC 2, но в любом случае, вот мой код контроллера, просто чтобы показать, как легко это сделать. Помните, моя цель концепции была в том, чтобы заставить модальные окна работать таким образом, чтобы мне не нужно было вносить какие-либо изменения в коде, кроме настройки какой-то базовой инфраструктуры.

    [UrlRoute(Path="edit/food")]
    public ActionResult EditFood()
    {            
        return View(new Food());
    }

    [HttpPost][UrlRoute(Path = "edit/food")]
    public ActionResult EditFood(Food food)
    {          
        return View(food);
    }
0 голосов
/ 04 декабря 2009

При создании URL для jQuery для выполнения AJAX GET вы можете добавить параметр строки запроса, такой как & javascriptWindow = id, при обнаружении этого в контроллере вы можете добавить необходимую логику в форму, чтобы закрыть диалог после исполнения.

...