web-dev-qa-db-ja.com

ASP.NET MVCのボタンクリックでの部分ビューのレンダリング

私が説明する問題は、すでに見つけたものと非常に似ています(例: ほぼ同じ名前のこの投稿 )が、重複しないものにできることを願っています。

Visual Studioで新しいASP.NET MVC 5アプリケーションを作成しました。次に、2つのモデルクラスを定義しました。

public class SearchCriterionModel
{
  public string Keyword { get; set; }
}

public class SearchResultModel
{
  public int Id { get; set; }
  public string FirstName { get; set; }
  public string Surname { get; set; }
}

次に、次のようにSearchControllerを作成しました。

public class SearchController : Controller
{
  public ActionResult Index()
  {
    return View();
  }

  public ActionResult DisplaySearchResults()
  {
    var model = new List<SearchResultModel>
    {
      new SearchResultModel { Id=1, FirstName="Peter", Surname="Pan" },
      new SearchResultModel { Id=2, FirstName="Jane", Surname="Doe" }
    };
    return PartialView("SearchResults", model);
  }
}

ビューIndex.cshtml(モデルおよびテンプレートとしてSearchCriterionModelを使用して厳密に入力編集)およびSearchResults.cshtmlとしてpartialビュータイプIEnumerable<SearchResultModel>(テンプレートリスト)。

これはインデックスビューです。

@model WebApplication1.Models.SearchCriterionModel

@{
  ViewBag.Title = "Index";
}

@using (Html.BeginForm())
{
  @Html.AntiForgeryToken()

  <div class="form-horizontal">
    <h4>SearchCriterionModel</h4>
    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    <div class="form-group">
      @Html.LabelFor(model => model.Keyword, htmlAttributes: new { @class = "control-label col-md-2" })
      <div class="col-md-10">
        @Html.EditorFor(model => model.Keyword, new { htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.Keyword, "", new { @class = "text-danger" })
      </div>
    </div>

    <div class="form-group">
      <div class="col-md-offset-2 col-md-10">
        <input type="button" id="btnDisplaySearchResults" value="Search" onclick="location.href='@Url.Action("DisplaySearchResults", "SearchController")'" />
      </div>
    </div>
  </div>
}

<div>
  @Html.ActionLink("Back to List", "Index")
</div>
<div id="searchResults">

</div>

ご覧のように、標準テンプレートの下にdivid="searchResults"を追加し、ボタンを編集しました。私が欲しいのは、ボタンがクリックされた後にのみ、下部のdivに部分ビューSearchResults.cshtmlを表示することです。 @Html.Partial("SearchResults", ViewBag.MyData)を使用してそこに部分的なビューを表示することに成功しましたが、親ビューが初めてロードされ、Index()メソッドにViewBag.MyDataを設定するとレンダリングされます。私が望むものではありません。

要約:ボタンをクリックすると、List of SearchResultModelインスタンスを(データベースアクセス経由で)取得し、この新しく取得したデータをモデルとして使用して、部分ビューをレンダリングする必要があります。 どうすればこれを達成できますか?上記のコードでボタンのクリックに反応する最初のステップですでに失敗しているようです。今、URL ~/Search/DisplaySearchResultsに移動しますが、もちろん何もありませんし、分離コードメソッドは呼び出されません。従来のASP.NETでは、サーバー側のOnClickハンドラーを追加し、グリッドのDataSourceを設定して、グリッドを表示するだけでした。しかし、MVCでは、この単純なタスクですでに失敗しています...

更新:ボタンを@Html.ActionLinkに変更するコントローラーメソッドを最後に入力できます。しかし当然、部分ビューを返すため、ページ全体のコンテンツとして表示されます。質問は次のとおりです。クライアント側の特定のdiv内にレンダリングされるように部分ビューを指示するにはどうすればよいですか?

24
InvisiblePanda

ボタンを変更します

<button id="search">Search</button>

次のスクリプトを追加します

var url = '@Url.Action("DisplaySearchResults", "Search")';
$('#search').click(function() {
  var keyWord = $('#Keyword').val();
  $('#searchResults').load(url, { searchText: keyWord });
})

コントローラーメソッドを変更して、検索テキストを受け入れます

public ActionResult DisplaySearchResults(string searchText)
{
  var model = // build list based on parameter searchText
   return PartialView("SearchResults", model);
}

JQuery .loadメソッドはコントローラーメソッドを呼び出し、検索テキストの値を渡し、<div>の内容を部分ビューで更新します。

サイドノート:<form>タグと@Html.ValidationSummary()および@Html.ValidationMessageFor()の使用は、おそらくここでは必要ありません。 Indexビューを返さないのでValidationSummaryは意味がなく、すべての結果を返すためにnull検索テキストが必要であり、いずれの場合もプロパティの検証属性がないと仮定しますKeywordので、検証するものはありません。

編集

SearchCriterionModelに検証属性を持つ複数のプロパティが含まれるというOPのコメントに基づいて、アプローチは送信ボタンを含め、フォーム.submit()イベントを処理します

<input type="submit" value="Search" />

var url = '@Url.Action("DisplaySearchResults", "Search")';
$('form').submit(function() {
  if (!$(this).valid()) { 
    return false; // prevent the ajax call if validation errors
  }
  var form = $(this).serialize();
  $('#searchResults').load(url, form);
  return false; // prevent the default submit action
})

コントローラーのメソッドは

public ActionResult DisplaySearchResults(SearchCriterionModel criteria)
{
  var model = // build list based on the properties of criteria
  return PartialView("SearchResults", model);
}
56
user3559349

これがコントローラーのコードです。

public IActionResult AddURLTest()
{
    return ViewComponent("AddURL");
}

JQueryロードメソッドを使用してロードできます。

$(document).ready (function(){
    $("#LoadSignIn").click(function(){
        $('#UserControl').load("/Home/AddURLTest");
    });
});

ソース コードリンク