ASP.NET Core 部分ビューで子要素を切り替える
2020/07/04 (更新:2020/11/19)
概要
環境や条件等に応じ画面項目をカスタマイズする画面のコントロール制御を想定しています。
画面項目を部分ビュータグヘルパーで実装し、指定された要素に応じて子要素を編集します。
サンプルは、ビューモデルの定義に従い項目毎にコントロールを切り替えます。
リポジトリです。
github.com/tassk-work/AspNetCore/tree/master/PartialView01
実装
画面項目毎に子要素を切り替える制御項目をビューモデルに定義します。
表示する子要素のタグ名を指定します。
ビューモデル
public class HomeViewModel
{
public string Item01 { get; set; }
public List<(string itemId, List children)> ChildMaster { get; set; }
public List Item01s { set; get; }
}
ラベル+コントロール構成の画面項目を、部分ビュータグヘルパーで実装します。
切り替え対象の子要素のタグ名は「タグ名N」形式とします。
部分ビュータグヘルパー
[HtmlTargetElement(TAG_NAME)]
public class SampleTagHelper : PartialTagHelper
{
public const string TAG_NAME = "sample";
private const string ItemIdAttributeName = "itemid";
private const string ChildAttributeName = "child";
[HtmlAttributeName(ItemIdAttributeName)]
public string ItemId { get; set; }
[HtmlAttributeName(ChildAttributeName)]
public List Children { get; set; }
public string InnerHtml { get; private set; }
public string ChildHtml
{
get
{
var html = InnerHtml;
foreach (var tag in Children)
html = Regex.Replace(html, $"<{tag}>(.*){tag}>", "$1", RegexOptions.Singleline);
html = Regex.Replace(html, $@"<{TAG_NAME}\d>(.*){TAG_NAME}\d>", "", RegexOptions.Singleline);
return html;
}
}
public SampleTagHelper(
ICompositeViewEngine viewEngine,
IViewBufferScope viewBufferScope) : base(viewEngine, viewBufferScope)
{
Model = this;
Name = "_Sample";
}
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
InnerHtml = (await output.GetChildContentAsync()).GetContent();
var viewModel = ViewContext.ViewData.Model as HomeViewModel;
Children ??= viewModel.ChildMaster.FirstOrDefault(x => x.itemId == ItemId).children;
await base.ProcessAsync(context, output);
}
}
部分ビュー
<div class="form-group">
@Html.Raw(Model.ChildHtml)
</div>
部分ビューに切り替えるコントロールを子要素で配置します。
ビュー
<div>
<sample itemid="@nameof(Model.Item01)">
<label asp-for="Item01"></label>
<sample1><select asp-for="Item01" asp-items="Model.Item01s"></select></sample1>
<sample2><label>@Model.Item01</label></sample2>
</sample>
</div>
コメント
コメントはありません。