代码之家  ›  专栏  ›  技术社区  ›  David Fox

.NETMVC如何呈现基于外部XML的表单?

  •  1
  • David Fox  · 技术社区  · 14 年前

    例如,第一个脚本可能是“谢谢你打电话来,我能帮你什么?”并包含一些输入元素。单击此屏幕上的“下一步”按钮后,它们将显示另一个窗体和另一个脚本,其中包含更多输入元素。

    之后 (之前)上面提到的两个屏幕使用从外部文件读取的轻量级XML样式语言?此文件将包含简单的、不可由开发人员读取的标记,如 <text>blah blah blah</text> , <button>Next</button> 被…包围 <screen></screen> <div> 可缓存 因此,当用户登录或应用程序进程中的某个较早时间时,所有屏幕都可以隐藏加载。

    到目前为止,我只想到了按钮.onclick要隐藏当前div并显示下一个div。我不确定如何使用MVC在某个时间之前将所有这些数据推送到客户端。我认为Cookies太小了,不能缓存大块的文本。我应该看看画面吗::颤抖::?

    基本上,这个.NETMVC应用程序需要基于外部源动态缓存视图,以创建一个非开发人员可以修改的屏幕“动态”工作流。可以强制用户注销并重新登录以重新缓存这些屏幕。

    请让我知道,如果这是不清楚的,我很高兴详细说明。

    1 回复  |  直到 14 年前
        1
  •  1
  •   Darin Dimitrov    14 年前

    首先,设计您想要的每个页面及其输入字段。然后可以定义视图模型、控制器和相应的视图。它可能看起来像这样(过于简单化):

    视图模型:

    /// <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
    }
    
    ...
    

    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) %>