1

私はここのユーザーと同様のものを持っています: ASP.NET MVC 3.0 WebGrid - Ajax Enabled とここ: http://social.msdn.microsoft.com/Forums/en-US/iewebdevelopment/thread/22be0501-1b0b-496a- 9d0c-f9f5138996ac

ただし、これらのスレッドからの提案はどれもここでは役に立ちません。

詳細: Windows 7/IIS 8 マシンのローカル デバッガーで実行すると、ajax ポストバックが更新を試みた後、「"WebGrid" ヘルパーで Ajax サポートを有効にするには、jQuery スクリプト参照が必要です」というメッセージが表示されます。 . ただし、FF で、またはサーバー (IIS 6) で実行されている同じコードのバージョンに対して IE を使用する場合、同じコードは問題になりません。さらに混乱させるために、私がこのコードを最初に書いたとき、この問題は一度もありませんでした.最近になってエラーが発生し始めました.

エラーが発生すると、ページ全体が部分ビューのみにリダイレクトされ、ポップアップが画面にスローされる前に、「正しい」更新されたコンテンツが画面上で点滅します。正しく動作しているように見えますが、何かがリセットされ、ajax の使用が停止します。

トラブルシューティングを試みるために、jquery の .min バージョンをフル バージョンに置き換え、コードをステップ実行しました。デバッガーでは、jQuery の動作が異なり、グローバル ajax カウンターの値が原因で "ajaxStop" がトリガーされます。同じ IE ブラウザーで同じコードのサーバー バージョンに対して外部スクリプト デバッガーを実行すると、これは発生しないように見えます (ただし、サーバーにはまだ「最小」バージョンがあるため、正確にはわかりません)。この ajaxStop が、jQuery がページに読み込まれておらず、ajax の動作を「固執」させず、部分ビューだけの新しいページの読み込みを強制していると webgrid に思わせているようです。

私のページは非常に単純ではありません: メイン ビューには部分ビューを含むいくつかの div があります。divSearch には ajax ポストバックを呼び出す検索部分ビューが含まれ、divList には検索結果に基づいて更新する必要があるグリッドが含まれます。検索部分ビューによって呼び出されるコントローラー メソッドは、検索結果の「新しい」コンテンツを文字列にレンダリングし、それらを JsonResult の一部として送り返します。これは、jQuery を介して divList の html に割り当てられます。(私はこの手法をアプリのいくつかの場所で使用しており、返された文字列が部分ビューの正しいコンテンツであることを確認しました)

jQuery (および他のすべての js インクルード) は、レイアウト ページの上部にあり、部分ビューの前にレンダリングされます。

メイン ビュー:

 @model WebUI.Areas.Admin.Models.Client.ManageClientsModel
 @{
    ViewBag.Title = "ManageClients";
    Layout = "~/Views/Shared/_AdminLayout.cshtml";
}
<style type="text/css">
.inv
{
    visibility: hidden;
}
.vis
{
    visibility: visible; 
}
</style>

<h2>ManageClients</h2>
<div id="divSearch">
    @Html.Partial("_ClientSearch", Model.ClientList)
</div>
<div id="divList">
    @Html.Partial("_ClientList", Model.ClientList)
</div>
<br/>
<div id="newSection">

    <div id="divEdit"> <button class="toggleNew">
       Add Client
       </button>
    </div>
    div class="inv" id="divNew">  @Html.Partial("_Create", Model.ClientVM ) </div>
</div>
<script type="text/javascript">
   $(function () {
    $(".toggleNew").click(function () {
        $("#divNew").toggleClass("inv");
        return false;
    });
   });

</script>

クライアント検索の一部:

 @using  Core.Entities
 @model  WebUI.Areas.Admin.Models.Client.ClientListViewModel
 <div id="clientSearch">
     <form action="@Url.Action("JsonSearch","Client", new { area = "Admin"})"  
                 onsubmit="return formSearchSubmit(this);"  >
         <div class="divReturnErrors"></div>
     @if(TempData["SearchName"] == null)
     {
         TempData["SearchName"] = Model.SearchName;
     }
         <br/>
         @Html.LabelFor(model => model.SearchName, "Search for client name:")
         @Html.EditorFor(model => model.SearchName)
          <input type="submit" value="Search" name="btnSearch"   />
     </form>
 </div>
 <script type="text/javascript">
   function formSearchSubmit(formToSubmit) {
     //this line submits the form data to the JsonSearch method
      $.post($(formToSubmit).attr("action"),
             { SearchName: $(formToSubmit).find("#SearchName").val() },
        function (data) {  //this is the callback from JsonSearch
                                        // that handles the results.
          if (data["IsSuccess"] == undefined || data["IsSuccess"] == false)
            $('div.divReturnErrors').html(data["Errors"]); 
                              //put errors in divReturnErrors
          else { //if it succeeds we stuff the string containing the 
                              //partial view into the _ClientList control's div to 
                             //replace previous grid.
                    $("#divList").html(data["PartialViewHtml"]);
                }
            }, "json");

                       return false;
             }  
</script>

クライアント リストの部分ビュー

 @model WebUI.Areas.Admin.Models.Client.ClientListViewModel
 <h2>Clients</h2>
  @helper TrueFalseToYesNo(bool val) {
    if (val)
    {
       <span>Yes</span>
    }
    else
    {
       <span>No</span>
    }
   }
<div id="clientListing">

  @{
    if(Model.SearchName != null)
    {
        TempData["SearchName"] = Model.SearchName;
    }

    var grid = new WebGrid<NeedleFinder.Core.Entities.Client>(null, rowsPerPage: 10, 
              canSort: false, defaultSort: "ClientName", 
                       ajaxUpdateContainerId:"clientListing");
    grid.Bind(Model.Clients, rowCount: Model.TotalRows, autoSortAndPage: false);
    @grid.GetHtml(htmlAttributes: new {id= "clientListing"},
        tableStyle: "table90",
        alternatingRowStyle: "duncanTableAltRows",
        headerStyle: "duncanTableHeaders",
        columns: grid.Columns(
            grid.Column(columnName: "Client ID", style: "logcolumn", 
                    format: item =>              
                    @Ajax.ActionLink(((object)item.ClientID).ToString(), 
                    Model.LinkAction, new { id = item.ClientID }, new AjaxOptions { 
                    HttpMethod = "GET", UpdateTargetId = "divEdit", InsertionMode = 
                    InsertionMode.Replace })),
            grid.Column(columnName: "ClientName", style: "logcolumn"),
            grid.Column(columnName: "Abbreviation", style: "logcolumn"),
            //grid.Column(columnName: "IsActive", style: "logcolumn")
            grid.Column(columnName: "IsActive", style: "logcolumn", 
               format: item => @TrueFalseToYesNo(item.IsActive))
            )
               )
       }
</div>

「エラー」は次の行で発生しています: $("#divList").html(data["PartialViewHtml"]); Client Search 部分ビュー ajax コールバック関数から。この行は jQuery にジャンプし、その中で ajaxStop を呼び出しています。

私はすでに他のスレッドからの提案を取り入れていることに注意してください (jQuery は上部に含まれ、ajaxUpdateContainer ターゲットと同じ名前の div に webgrid を配置し、同じ名前の webgrid に id プロパティを追加します。 document.ready で部分を明示的にロードすることは、部分ビューのデフォルトの「get」バージョンを単純にロードするのではなく、入力に基づいてこの div に文字列を入力しようとしているため、私には当てはまらないようです。

ページが最初にロードされたときにレンダリングされた html は次のとおりです (とにかく ajax 投稿を行っても更新されません):

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>ManageClients</title>
<link href="/Content/Site.css" rel="stylesheet" type="text/css" />
<link href="/Content/themes/redmond/jquery-ui.css" rel="stylesheet" type="text/css" />

<script src="/Scripts/jquery-1.5.1.js" type="text/javascript"></script>
<script src="/Scripts/jquery-ui-1.8.18.js" type="text/javascript"></script>
<script src="/Scripts/jquery.unobtrusive-ajax.js" type="text/javascript"></script>
<script src="/Scripts/modernizr-1.7.js" type="text/javascript"></script>
<script src="/Scripts/jQuery.Validate.js" type="text/javascript"></script>
<script src="/Scripts/jquery.validate.unobtrusive.js" type="text/javascript"></script>
</head>
<script type="text/javascript">

$(document).ready(function () {
    $('.dateEditor').datepicker({ dateFormat: "mm/dd/yy" });
});

//This function should be called in your ajax post return are staying on same page
     after success and/or you do have server side errors that couldn't have been found
//if there were still client side errors, otherwise you will still have the previous 
 validation errors.

function ClearValidationErrors() {

    var container = $('form').find('[data-valmsg-summary="true"]');
    var list = container.find('ul');

    if (list && list.length) {
        list.empty();
        container.addClass('validation-summary-valid').removeClass('validation-summary-
         errors');
    }
}


</script>
<body>
<style type="text/css">
#topbar
{
    background-color: Black;
    margin: 0px;
    padding: 5px;
}

#adminmenu_nav a
{
    float: left;
    width: 150px;
}

.logcolumn
{
    padding-left: 10px;
    padding-right: 10px;
    border: 1px solid #BBBBBB;
}

</style>
<script>
$(function () {
    $("#adminmenu_nav a").button();
    $("#optionsPanel input").button();
    $(".asButton input").button();
});
</script>
<div id="topbar">
<img style="margin-left:20px" src="/Content/Images/Logos/NFWhite.png" 
alt="NeedleFinder" />
</div>
<div>
<div id="adminmenu_nav" style="float: left">
    <table>
        <tr><td><a href="/Admin/Client/ManageClients">Clients</a></td></tr>
        <tr><td>Cases</td></tr>
        <tr><td><a href="/Admin/User/ManageUsers">Users</a></td></tr>
        <tr><td>Roles</td></tr>
        <tr><td><a href="/Admin/Logging/Summary">Logs</a></td></tr>
    </table>
</div>
<div style="overflow: hidden">
    <span class="validation-summary-errors"></span>
    <style type="text/css">
.inv
{
  visibility: hidden;
}
.vis
{
    visibility: visible; 
}
</style>

<h2>ManageClients</h2>
<div id="divSearch">
  <div id="clientSearch">
   <form action="/Admin/Client/JsonSearch" onsubmit="return formSearchSubmit(this);"  >
        <div class="divReturnErrors"></div>
        <br/>
        <label for="SearchName">Search for client name:</label>
        <input class="text-box single-line" id="SearchName" name="SearchName" 
          type="text" value="" />
         <input type="submit" value="Search" name="btnSearch"   />
    </form>
</div>
<script type="text/javascript">
function formSearchSubmit(formToSubmit) {
    //this line submits the form data to the JsonSearch method
    $.post($(formToSubmit).attr("action"),
            { SearchName: $(formToSubmit).find("#SearchName").val() },
        function (data) {  
        if (data["IsSuccess"] == undefined || data["IsSuccess"] == false)
            $('div.divReturnErrors').html(data["Errors"]); 
         else 
                     { 
            $("#divList").html(data["PartialViewHtml"]);
        }
    }, "json");

    return false;
    }  
</script>
</div>
<div id="divList">
  <h2>Clients</h2>

  <div id="clientListing">

<script type="text/javascript">if (typeof(jQuery)=='undefined') alert("A jQuery script 
reference is required in order to enable Ajax support in the \"WebGrid\" helper.");
</script><table class="table90" id="clientListing"><thead><tr 
  class="duncanTableHeaders"><th scope="col">Client ID</th><th 
  scope="col">ClientName</th><th scope="col">Abbreviation</th><th 
  scope="col">IsActive</th></tr></thead><tfoot><tr><td colspan="4">1 <a href="#" 
  onclick="$(&#39;#clientListing&#39;).load(&#39;/Admin/Client/ManageClients?page=2&
  amp;__=634750282355486955 #clientListing&#39;);">2</a> <a href="#" 
  onclick="$(&#39;#clientListing&#39;).load(&#39;/Admin/Client/ManageClients?page=3&
  amp;__=634750282355506956 #clientListing&#39;);">3</a> <a href="#" 
  onclick="$(&#39;#clientListing&#39;).load(&#39;/Admin/Client/ManageClients?page=4&
  amp;__=634750282355516957 #clientListing&#39;);">4</a> <a href="#" 
  onclick="$(&#39;#clientListing&#39;).load(&#39;/Admin/Client/ManageClients?page=5&
  amp;__=634750282355536958 #clientListing&#39;);">5</a> <a href="#" 
  onclick="$(&#39;#clientListing&#39;).load(&#39;/Admin/Client/ManageClients?page=2& 
  amp;__=634750282355546959 #clientListing&#39;);">&gt;</a> </td></tr></tfoot><tbody>
  <tr><td class="logcolumn"><a data-ajax="true" data-ajax-method="GET" data-ajax-
  mode="replace" data-ajax-update="#divEdit" href="/Admin/Client/_Edit/2042">2042</a>
  </td><td class="logcolumn">ABC Legal</td><td class="logcolumn">ABC123</td><td 
  class="logcolumn">           <span>Yes</span>

  </td></tr><tr class="duncanTableAltRows"><td class="logcolumn"><a data-ajax="true" 
  data-ajax-method="GET" data-ajax-mode="replace" data-ajax-update="#divEdit" 
  href="/Admin/Client/_Edit/2044">2044</a></td><td class="logcolumn">ABC Legal 
  3</td><td class="logcolumn">ABC125</td><td class="logcolumn">           
  <span>Yes</span>

  </td></tr><tr><td class="logcolumn"><a data-ajax="true" data-ajax-method="GET" 
  data-ajax-mode="replace" data-ajax-update="#divEdit" href="/Admin/Client/_Edit
  /2045">2045</a></td><td class="logcolumn">ABC Legal 4b</td><td 
  class="logcolumn">ABC4bb</td><td class="logcolumn">           <span>Yes</span>

  </td></tr><tr class="duncanTableAltRows"><td class="logcolumn"><a data-ajax="true" 
  data-ajax-method="GET" data-ajax-mode="replace" data-ajax-update="#divEdit" 
  href="/Admin/Client/_Edit/2047">2047</a></td><td class="logcolumn">ABC Legal 
  6</td><td class="logcolumn">ABC6</td><td class="logcolumn">           <span>No</span>

  </td></tr><tr><td class="logcolumn"><a data-ajax="true" data-ajax-method="GET" 
  data-ajax-mode="replace" data-ajax-update="#divEdit" href="/Admin/Client/_Edit
  /2048">2048</a></td><td class="logcolumn">ABC Legal 7</td><td 
  class="logcolumn">ABC7</td><td class="logcolumn">           <span>Yes</span>

  </td></tr><tr class="duncanTableAltRows"><td class="logcolumn"><a data-ajax="true"   
  data-ajax-method="GET" data-ajax-mode="replace" data-ajax-update="#divEdit" 
  href="/Admin/Client/_Edit/2049">2049</a></td><td class="logcolumn">ABC Legal 
  8a</td><td class="logcolumn">ABC8a</td><td class="logcolumn">           
  <span>Yes</span>

  </td></tr><tr><td class="logcolumn"><a data-ajax="true" data-ajax-method="GET" 
  data-ajax-mode="replace" data-ajax-update="#divEdit" href="/Admin/Client/_Edit
  /2050">2050</a></td><td class="logcolumn">ABC Legal 9</td><td 
  class="logcolumn">ABC9</td><td class="logcolumn">           <span>Yes</span>

  </td></tr><tr class="duncanTableAltRows"><td class="logcolumn"><a data-ajax="true" 
  data-ajax-method="GET" data-ajax-mode="replace" data-ajax-update="#divEdit" 
  href="/Admin/Client/_Edit/2043">2043</a></td><td class="logcolumn">ABC 
  Legal2</td><td class="logcolumn">ABC124</td><td class="logcolumn">           
  <span>Yes</span>
  </td></tr><tr><td class="logcolumn"><a data-ajax="true" data-ajax-method="GET" 
  data-ajax-mode="replace" data-ajax-update="#divEdit" href="/Admin/Client/_Edit
  /2046">2046</a></td><td class="logcolumn">ABC Legal5</td><td 
  class="logcolumn">ABC5</td><td class="logcolumn">           <span>Yes</span>
  </td></tr><tr class="duncanTableAltRows"><td class="logcolumn"><a data-ajax="true" 
  data-ajax-method="GET" data-ajax-mode="replace" data-ajax-update="#divEdit" 
  href="/Admin/Client/_Edit/2051">2051</a></td><td class="logcolumn">ACE Legal 
  1</td><td class="logcolumn">ACE1</td><td class="logcolumn">           
  <span>Yes</span>

  </td></tr></tbody></table></div>


  </div>
<br/>
<div id="newSection">

   <div id="divEdit"> <button class="toggleNew">
     Add Client
  </button></div><!-- placeholder for _Edit., will replace button when editing//-->
  <div class="inv" id="divNew">
 <form action="/Admin/Client/JsonCreate" onsubmit="return formCreateSubmit(this);">
  <div>
    <div class="titleText">Add Client</div>
    <div class="divClientSideVal">
    <div class="validation-summary-valid" data-valmsg-summary="true"><ul><li 
      style="display:none"></li>
    </ul></div>
    </div>
    <div class="divCreateErrors"></div>
    <fieldset>
        <table>

            <tr>
                <td>
                    <label for="CurrentClient_ClientName">Name</label>
                </td>
                <td><input data-val="true" data-val-length="Client Name must be 50 
                       characters or fewer" data-val-length-max="50" data-val-
                      required="Client Name is required." 
                     id="CurrentClient_ClientName" name="CurrentClient.ClientName" 
                      style="width: 120px;" type="text" value="" /> 
                </td>
                <td><span class="field-validation-valid" data-valmsg-
               for="CurrentClient.ClientName" data-valmsg-replace="false">*</span></td>
            </tr>
            <tr>
                <td>
                    <label for="CurrentClient_Abbreviation">Abbreviation</label>
                </td>
                <td><input data-val="true" data-val-length="Abbreviation must be 6 
                characters or fewer" data-val-length-max="6" data-val-
                required="Abbreviation is required." id="CurrentClient_Abbreviation" 
                name="CurrentClient.Abbreviation" style="width: 120px;" type="text" 
                value="" />
                </td>
                <td><span class="field-validation-valid" data-valmsg-
               for="CurrentClient.ClientName" data-valmsg-replace="false">*</span></td>
            </tr>
            <tr>
                <td>
                    <label for="CurrentClient_IsActive">Is Active:</label>
                </td>
                <td>

                <input data-val="true" data-val-required="The IsActive field is 
                required." id="CurrentClient_IsActive" name="CurrentClient.IsActive" 
                 type="checkbox" value="true" /><input name="CurrentClient.IsActive" 
                  type="hidden" value="false" />
                </td>
            </tr>
            <tr>
                <td>Enable for installations:</td>
                <td>
                    <select Multiple="multiple" id="SelectedInstallations" 
              multiple="multiple" name="SelectedInstallations" style="width: 
               120px;">       
                 <option value="1">Dev</option>
                 <option value="2">FakeDev</option>
                </select>
                </td>
            </tr>
        </table></fieldset>
    <p>
        <input type="submit" value="Create" name="btnCreate"  />
    </p>
</div>
</form>

<script type="text/javascript">


function formCreateSubmit(formToSubmit) {

    var installations = "";
    $('#SelectedInstallations option').each(function (i) {
        if (this.selected == true) {
            if (installations.length > 0) {
                installations += ",";
            }
            installations += this.value;
        }
    });

    //this line submits the form data to the JsonCreate method
    $.post($(formToSubmit).attr("action"),
            { ClientName: $(formToSubmit).find("#CurrentClient_ClientName").val(),
                Abbreviation:  
               $(formToSubmit).find("#CurrentClient_Abbreviation").val(),
                IsActive: 
             $(formToSubmit).find("#CurrentClient_IsActive").is(':checked'),
                SelectedInstallations: installations,
                Action: "Create"
            },
    function (data) {  
    if (data["IsSuccess"] == undefined ||  data["IsSuccess"] == false)
    {
       if (data["Errors"] != undefined &&                          
                   data["Errors"].length > 0) 
                {
                        ClearValidationErrors();                    

     ('div.divCreateErrors').html(data["Errors"]);                      
      } else {
$('div.divCreateErrors').html("");
   }

} else { 
        window.location = "/Admin/Client/ManageClients";
    }
}, "json");

    return false;
   }
</script> </div><!-- placeholder for _Create //-->
</div>
<script type="text/javascript">
   $(function () {
    $(".toggleNew").click(function () {
        $("#divNew").toggleClass("inv");
        return false;
    });
   });

</script>



  </div>
</div>
  <div class="InternalMenu"><a href="/Admin/Logging">Logging</a> - <a href="/Admin
          /Client/ManageClients">Client</a></div>
  </body>
</html>

問題の原因について私はかなり困惑しているので、どんな提案も大歓迎です。

4

1 に答える 1

0

わかりました-問題がわかりましたので、報告します。

この問題は、実際には jQuery 関連よりも MVC に関連していましたが、検索フォームをどのようにまとめたかに問題がありました。

検索ボタンに type=submit を設定し、onsubmit イベントハンドラで ajax ポストバックを実行しました。何が起こっていたのかというと、ajax ポストバックは想定どおりの動作をしていましたが、完了すると、送信が「get」をトリガーし、検索フォームのコントローラーの「get」ハンドラーがただ PartialViewResult を返すということでした。これは、通常のロードとして画面の内容を置き換えていました。部分ビューに含まれているレイアウトがないため、エラーがスローされていました。

したがって、修正は、a) ボタンの種類を「ボタン」に変更する b) フォーム宣言から「onsubmit」を削除する c) フォームに id="frmSearch" を追加する (簡単に選択できるようにするため) d) formSearchSubmit を変更して取得する関数の引数 (フォームではなくボタン) からではなく、$("#frmSearch").action からのアクション。

その後、ajax投稿を正しく送信し、フォームの別の送信をトリガーすることなく、戻り更新を処理しました。

于 2012-06-12T17:16:16.320 に答える