Как .NET MVC может отображать формы на основе внешнего XML? - PullRequest
1 голос
/ 01 сентября 2010

Не разработчик хочет иметь возможность изменять сценарии, которые пользователи читают на нескольких экранах.

Например, первый сценарий может гласить: «Спасибо за звонок, чем я могу вам помочь?» и содержат некоторые элементы ввода. После нажатия кнопки «Далее» на этом экране им предоставляется другая форма с другим сценарием с большим количеством элементов ввода.

Как они могут «вставить» экран между ( или после или до) двумя упомянутыми выше экранами с облегченным языком в стиле XML, читаемым из внешнего файла? Этот файл будет содержать простые не читаемые разработчиками теги, такие как <text>blah blah blah</text>, <button>Next</button>, окруженные <screen></screen>, которые я мог бы перевести в скрываемые и отображаемые теги <div>. Он также должен быть с возможностью кэширования , чтобы все экраны могли загружаться скрытыми при входе пользователя в систему или на более раннем этапе процесса приложения.

Все, что я до сих пор придумал, это jQuery в кнопке. Нажмите, чтобы скрыть текущий div и показать следующий. Я не уверен, как использовать MVC для передачи всех этих данных клиенту в какой-то момент времени. Я думаю, что файлы cookie слишком малы для кэширования больших кусков текста. Должен ли я смотреть в кадры :: shudder ::?

По сути, это приложение .NET MVC должно динамически кэшировать представления на основе внешнего источника, чтобы создать «динамический» рабочий процесс экранов, которые могут быть изменены не разработчиками. Можно заставить пользователей выйти из системы и снова войти в нее для повторного кэширования этих экранов.

Пожалуйста, дайте мне знать, если это неясно, я с удовольствием уточню.

1 Ответ

1 голос
/ 01 сентября 2010

Вот что вы можете попробовать:

Начните с разработки каждой страницы, которую вы хотели бы иметь с ее полями ввода. Затем вы можете определить ViewModels, Controllers и соответствующие виды. Это может выглядеть примерно так (упрощенно):

ViewModels:

/// <summary>
/// Represents a button with its text and 
/// the controller name it will redirect to
/// </summary>
public class Button
{
    public string Text { get; set; }
    public string Controller { get; set; }
}

/// <summary>
/// Represents the page with a header and a list of buttons
/// </summary>
public class Page
{
    public string Header { get; set; }
    public IEnumerable<Button> Buttons { get; set; }
}

/// <summary>
/// Each view model will have page metadata
/// </summary>
public abstract class BaseViewModel
{
    public Page Page { get; set; }
}

public class Page1ViewModel : BaseViewModel
{
    // Put any properties specific to this page
    // which will be used for the input fields
}

public class Page2ViewModel : BaseViewModel
{
    // Put any properties specific to this page
    // which will be used for the input fields
}

...

Затем создайте репозиторий, который будет анализировать XML (реализация оставлена ​​для краткости):

public interface IPagesRepository
{
    Page ReadPage(string pageName);
}

Тогда вот как может выглядеть контроллер страницы:

public class Page1Controller : Controller
{
    private readonly IPagesRepository _repository;
    // TODO: to avoid repeating this ctor you could have 
    // a base repository controller which others derive from
    public Page1Controller(IPagesRepository repository)
    {
        _repository = repository;
    }

    public ActionResult Index()
    {
        var model = new Page1ViewModel();
        model.Page = _repository.ReadPage("page1");
        //model.Page = new Page
        //{
        //    Header = "Thanks for calling, how may I help you?",
        //    Buttons = new[] 
        //    {
        //        new Button { Text = "Next", Controller = "Page2" },
        //        new Button { Text = "Address", Controller = "Page3" },
        //    }
        //};
        return View(model);
    }

    [HttpPost]
    public ActionResult Index(Page1ViewModel model, string redirectTo)
    {
        if (!ModelState.IsValid)
        {
            return View(model);
        }
        return Redirect(redirectTo);
    }
}

И последняя часть - соответствующий вид:

<script type="text/javascript">
$(function () {
    // when a navigation link is clicked set the redirectTo 
    // hidden field to the value of the controller we
    // want to redirect to and submit the form
    $('.nav a').click(function () {
        $('form :hidden[name=redirectTo]').val(this.href);
        $('form').submit();
        return false;
    });
});
</script>

<h2><%: Model.Page.Header %></h2>

<%: Html.ValidationSummary() %>

<% using (Html.BeginForm()) { %>
    <%: Html.Hidden("redirectTo") %>
    <!-- TODO: Put here the specific input fields for this page -->
<% } %>

<div class="nav">
    <%: Html.EditorFor(x => x.Page.Buttons) %>
</div>

И Button.ascx Шаблон редактора, который будет отображать навигационные ссылки:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<SomeNs.Models.Button>" %>
<!-- Here we assume Index action is setup by default in the routes -->
<%: Html.ActionLink(Model.Text, "index", Model.Controller) %>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...