如何有条件地从标签助手中禁用 <select>?

How to conditionally disable <select> from tag helper?

我的目标是有条件地根据传递给视图的模型对象的状态禁用下拉菜单。

以下代码正确呈现禁用的 <select> 标记(但不是有条件的):

<select class="form-control" asp-for="Priority" asp-items="@priorityList" disabled></select>

以下没有。属性 disabled 未出现在呈现页面的页面源代码中:

@{ string disabled = Model.CaseMode == Mode.Active ? "" : "disabled"; }
<select class="form-control" asp-for="Priority" asp-items="@priorityList" @disabled></select>

此外,下面也没有禁用<select>标签。

<select class="form-control" asp-for="Priority" asp-items="@priorityList" @((Model.CaseMode == Mode.Closed) ? "disabled" : "")></select>

我认为这个问题与标签助手在模板中完成字符串替换之前处理 <select> 标签有关。谁能建议我如何有条件地禁用此元素,而不必在 if else 结构中呈现两个单独的元素?

默认的 select 标签助手无法实现,但您可以创建自己的标签助手,并将其配置为对接受布尔值的自定义 asp-disabled 属性作出反应。

在您看来:

<select class="form-control" asp-for="Priority" asp-items="@priorityList" asp-disabled="@(Model.CaseMode == Mode.Closed)"></select>

然后,创建您的 TagHelper class:

using Microsoft.AspNetCore.Razor.TagHelpers;
using System;

namespace YourNamespace.TagHelpers
{
    // Triggered on all select elements with the asp-disabled attribute
    [HtmlTargetElement("select", Attributes = DisabledAttributeName)]
    public class SelectTagHelper : TagHelper
    {
        private const string DisabledAttributeName = "asp-disabled";

        /// Get the value of the condition
        [HtmlAttributeName(DisabledAttributeName)]
        public bool Disabled { get; set; }

        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            if (context == null)
                throw new ArgumentNullException(nameof(context));

            if (output == null)
                throw new ArgumentNullException(nameof(output));

            if (Disabled)
                output.Attributes.SetAttribute("disabled", null);
        }
    }
}

为确保使用您的 TagHelper,您还需要在 _ViewImports.cshtml 中注册它:

@addTagHelper *, YourNamespace

无需创建自定义 TagHelper。试试这个。

<select class="form-control" asp-for="Priority" asp-items="@priorityList" disabled="@(true)"></select>
<select class="form-control" asp-for="Priority" asp-items="@priorityList" disabled="@(false)"></select>

此渲染:

<select class="form-control" id="Priority" name="Priority" disabled="disabled">...</select>
<select class="form-control" id="Priority" name="Priority">...</select>

我是从这里了解到的:https://github.com/aspnet/Mvc/issues/7333#issuecomment-363504164

因为 disabled="false" 对我不起作用并且不想为一个 select 列表添加扩展名 class...这是我解决它的方法:

@{ string disabled = Model.CaseMode == Mode.Active ? "disabled" : null; }
<select  asp-for="Priority" class="form-control" disabled="@disabled" asp-items="@priorityList"></select>

另一种可能的解决方案是将您的条件放入 ViewData 字典并在加载文档后进行评估:

@if((bool)ViewData["YourModelCondition"]){
     $('#selectListID').prop('disabled', 'disabled');
}

注意:如果您使用第二种解决方案,您将需要为 select 指定一个 ID。