私が説明する問題は、すでに見つけたものと非常に似ています(例: ほぼ同じ名前のこの投稿 )が、重複しないものにできることを願っています。
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>
ご覧のように、標準テンプレートの下にdiv
とid="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
内にレンダリングされるように部分ビューを指示するにはどうすればよいですか?
ボタンを変更します
<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);
}
これがコントローラーのコードです。
public IActionResult AddURLTest()
{
return ViewComponent("AddURL");
}
JQueryロードメソッドを使用してロードできます。
$(document).ready (function(){
$("#LoadSignIn").click(function(){
$('#UserControl').load("/Home/AddURLTest");
});
});
ソース コードリンク