1

我有一个表单,我需要一个接一个地调用两个操作方法。流程就是这样。

  • 首先,我检查用户是否输入了先决条件数据。如果不是,那么我会显示一条消息,用户需要先输入数据。
  • 如果输入了所有先决条件数据,我将调用一个返回数据的操作方法。如果没有返回数据,那么我会在同一页面上显示“未找到数据”消息。
  • 如果返回数据,那么我调用另一个控制器中存在的另一个操作方法,该方法在新选项卡中返回包含所有数据的视图。

风景:

@using (Ajax.BeginForm("Index", "OrderListItems", null, new AjaxOptions { OnBegin = "verifyRequiredData"}, new { @id = "formCreateOrderListReport", @target = "_blank" }))
{
    //Contains controls and a button 
}

此视图中的脚本:

        function verifyRequiredData() {            
            if ($("#dtScheduledDate").val() == "") {

                $('#dvValidationSummary').html("");
                var errorMessage = "";

                errorMessage = "<span>Please correct the following errors:</span><ul>";
                errorMessage += "<li>Please enter Scheduled date</li>";

                $('#dvValidationSummary').append(errorMessage);
                $('#dvValidationSummary').removeClass('validation-summary-valid').addClass('validation-summary-errors');

                return false;
            }
            else {
                $('#dvValidationSummary').addClass('validation-summary-valid').removeClass('validation-summary-errors');
                $('#dvValidationSummary').html("");

                $.ajax({
                    type: "GET",
                    url: '@Url.Action("GetOrderListReport", "OrderList")',                    
                    data: {
                        ScheduledDate: $("#dtScheduledDate").val(),
                        Crews: $('#selAddCrewMembers').val(),
                        Priorities: $('#selPriority').val(),
                        ServiceTypes: $('#selServiceTypes').val(),
                        IsMeterInfoRequired: $('#chkPrintMeterInfo').val()
                    },
                    cache: false,                    
                    success: function (data) {
                        debugger;
                        if (data !== "No data found") {
                            //var newUrl = '@Url.Action("Index", "OrderListItems")';
                            //window.open(newUrl, '_blank');
                            return true;
                        } else {
                            //Show message "No data found"
                            return false;
                        }
                    }
                });
                return false;
            }
        }

“OrderList”控制器中的“GetOrderListReport”操作方法:

 public ActionResult GetOrderListReport(OrderListModel model)
 {
     var contract = new OrderReportDrilldownParamDataContract
     {             
         ScheduledDate = model.ScheduledDate
         //Setting other properties as well           
     };
     var result = OrderDataModel.GetOrderList(contract);

     if (string.IsNullOrWhiteSpace(result) || string.IsNullOrEmpty(result))
     {
         return Json("No data found", JsonRequestBehavior.AllowGet);             
     }

     var deserializedData = SO.Core.ExtensionMethods.DeserializeObjectFromJson<OrderReportDrilldownDataContract>(result);

     // send it to index method for list
     TempData["DataContract"] = deserializedData;
     return Json(deserializedData, JsonRequestBehavior.AllowGet);
    }

OrderListItems Controller 中存在的最后一个操作方法,其结果需要显示在新选项卡中:

public ActionResult Index()
{
    var deserializedData = TempData["DataContract"] as OrderReportDrilldownDataContract;
    var model = new OrderListItemViewModel(deserializedData);
    return View(model);
}

问题是我没有在新选项卡中看到这些数据,尽管我在 Ajax.BeginForm 中使用了 @target = "_blank"。如上所示,我也尝试过使用 window.open(newUrl, '_blank') 。但结果仍然没有显示在新选项卡中。

请协助我在哪里出错?

4

2 回答 2

1

这是我认为您正在尝试做的事情的骨架。请注意,window.open 是一个弹出窗口,大多数用户都会阻止弹出窗口。

<form id="formCreateOrderListReport">
    <input type="text" vaule="testing" name="id" id="id"/>
    <input type="submit" value="submit" />
</form>

<script type="text/javascript">
    $('#formCreateOrderListReport').on('submit', function (event) {
        $.ajax({
            type: "POST",
            url: '/home/test',
            data: { id: $('#id').val()},
            cache: false
        }).done(function () {
            debugger;
            alert("success");
            var newUrl = '/home/contact';
            window.open(newUrl, '_blank');
        }).fail(function () {
            debugger;
            alert("error");
        });
        return false;
    });
</script>

缩小应用程序以获得所需的 UI 流,然后使用数据。

于 2012-12-09T01:33:39.730 回答
1

如果您使用的是 Ajax.BeginForm,那么您不应该同时进行 ajax 发布,因为不显眼的 ajax 库会在提交表单时自动执行 ajax 发布。

此外,如果您使用带有数据注释验证和客户端不显眼验证的视图模型,则无需手动验证 begin ajax 回调中的数据,因为如果发现任何验证错误,则不会提交表单。

在这种情况下,您需要添加的唯一 javascript 代码是一段用于 ajax 成功回调的代码。这看起来就像您当前拥有的那样,但您需要考虑到在新标签中打开取决于浏览器和用户设置。它甚至可能被浏览器视为弹出窗口并被阻止,需要用户干预才能允许它们,就像在 IE8 中一样。你可以试试这个小提琴

所以这将是你的模型:

public class OrderListModel 
{
    [Required]
    public DateTime ScheduledDate { get; set; }

    //the other properties of the OrderListModel
}

表单将使用不显眼的 Ajax 发布到 OrderList 控制器的 GetOrderListReport。在成功回调中,您将检查响应,当它与“未找到数据”不同时,您将在新选项卡上手动打开 OrderListItems 页面。

这将是您的观点:

@model someNamespace.OrderListModel

<script type="text/javascript">
    function ViewOrderListItems(data){
        debugger;
        if (data !== "No data found") {
            var newUrl = '@Url.Action("Index", "OrderListItems")';
            //this will work or not depending on browser and user settings.
            //passing _newtab may work in Firefox too.
            window.open(newUrl, '_blank');
        } else {
            //Show message "No data found" somewhere in the current page
        }
    }
</script>

@using (Ajax.BeginForm("GetOrderListReport", "OrderList", null, 
                      new AjaxOptions { OnSucces= "ViewOrderListItems"}, 
                      new { @id = "formCreateOrderListReport" }))
{
    @Html.ValidationSummary(false)

    //input and submit buttons
    //for inputs, make sure to use the helpers like @Html.TextBoxFor(), @Html.CheckBoxFor(), etc
    //so the unobtrusive validation attributes are added to your input elements.
    //You may consider using @Html.ValidationMessageFor() so error messages are displayed next to the inputs instead in the validation summary
    //Example:
    <div>
        @Html.LabelFor(m => m.ScheduledDate)
    </div>
    <div>
        @Html.TextBoxFor(m => m.ScheduledDate, new {id = "dtScheduledDate"})
        @Html.ValidationMessageFor(m => m.ScheduledDate)
    </div>

    <input type="submit" value="Get Report" />
}

有了这个,您应该能够使用 ajax 在初始页面中发布数据。然后根据收到的响应,您将使用第二页内容 (OrderListItems) 打开另一个窗口\选项卡(如前所述,取决于浏览器和用户设置,这可能会在新窗口中打开甚至被阻止)。

于 2012-12-09T16:19:06.420 回答