1

2 つのアクション メソッドを順番に呼び出す必要があるフォームがあります。こんな流れです。

  • まず、前提条件データがユーザーによって入力されているかどうかを確認します。そうでない場合は、ユーザーが最初にデータを入力する必要があるというメッセージを表示します。
  • すべての前提データが入力されたら、データを返すアクション メソッドを呼び出します。データが返されない場合は、同じページに「データが見つかりません」というメッセージが表示されます。
  • データが返された場合は、別のコントローラーにある別のアクション メソッドを呼び出します。これにより、すべてのデータを含むビューが新しいタブに返されます。

景色:

@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 コントローラーに存在する最後のアクション メソッド。その結果を新しいタブに表示する必要があります。

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

Ajax.BeginForm を使用している場合は、フォームの送信時に目立たない ajax ライブラリが自動的に ajax 投稿を実行するため、ajax 投稿も行うべきではありません。

また、データ注釈の検証とクライアントの目立たない検証を備えたビューモデルを使用する場合、検証エラーが見つかった場合はフォームが送信されないため、begin ajax コールバックでデータを手動で検証する必要はありません。

このシナリオで追加する必要がある唯一の JavaScript コードは、ajax 成功コールバックのコードです。それはあなたが現在持っているものと同じように見えますが、新しいタブで開くことはブラウザとユーザー設定に依存することを考慮する必要があります. ブラウザによってポップアップと見なされてブロックされることもあり、IE8 のように許可するにはユーザーの介入が必要です。この fiddleで試してみることができます。

したがって、これはあなたのモデルになります:

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 を使用して最初のページにデータを投稿できるようになります。次に、受信した応答に基づいて、2 番目のページ コンテンツ (OrderListItems) を含む別のウィンドウ\タブを開きます (前述のように、ブラウザーとユーザーの設定によっては、新しいウィンドウで開かれるか、ブロックされる場合もあります)。

于 2012-12-09T16:19:06.420 に答える
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 に答える