MVC 3 + nockoutjs: добавление атрибута связывания данных при использовании Editorfor для логического поля

StackOverflow https://stackoverflow.com/questions/7302434

  •  22-10-2019
  •  | 
  •  

Вопрос

С использованием @Html.EditorFor(model =>model.IsClient), где isClient - логический Not Set, Yes and No как варианты.

Все хорошо и хорошо.

Теперь я хочу использовать nockoutjs с результирующим Dropdownlist, который мне нравится, так как же добавить атрибут связывания данных с помощью @html.editorfor, который мне нужен для нокаутирования, чтобы работать с этим раскрыванием?

Я пытался:

@Html.EditorFor(model => model.IsClient, new Dictionary<string, object> { { "data-bind", "value: Account.IsClient" } })

Тем не менее, это использует параметр AceplyViewData Object, и он не производит атрибут связок данных. Что, вероятно, вполне естественно, так как этот параметр, вероятно, не имеет ничего общего с атрибутами HTML для рендерированного тега.

Тем не менее, не может найти никакой разумной документации, и ни одна из других перегрузков не выглядит, вероятно, кандидатами за то, что я хочу.

Tia любые предложения.

Это было полезно?

Решение

Брэд Уилсон В блогах о шаблонах отображения и редактора в ASP.NET MVC 2. Таким образом, вы можете изменить шаблон по умолчанию для Boolean и добавить необходимые атрибуты (~/Views/Shared/EditorTemplates/MyTemplate.cshtml):

@{
    bool? value = null;
    if (ViewData.Model != null) 
    {
        value = Convert.ToBoolean(ViewData.Model, System.Globalization.CultureInfo.InvariantCulture);
    }

    var triStateValues = new List<SelectListItem> 
    {
        new SelectListItem 
        { 
            Text = "Not Set",
            Value = String.Empty,
            Selected = !value.HasValue 
        },
        new SelectListItem 
        { 
            Text = "True",
            Value = "true",
            Selected = value.HasValue && value.Value 
        },
        new SelectListItem 
        { 
            Text = "False",
            Value = "false",
            Selected = value.HasValue && !value.Value 
        },
    };
}

@if (ViewData.ModelMetadata.IsNullableValueType) 
{
    <!-- TODO: here you can use any attributes you like -->
    @Html.DropDownList(
        "", 
        triStateValues, 
        new { 
            @class = "list-box tri-state", 
            data_bind="value: " + ViewData.TemplateInfo.GetFullHtmlFieldName("") // you could also use ViewData.ModelMetadata.PropertyName if you want to get only the property name and not the entire navigation hierarchy name
        }
    )
} 
else 
{
    @Html.CheckBox("", value ?? false, new { @class = "check-box" })
}

и наконец:

@Html.EditorFor(model => model.IsClient, "MyTemplate")

или украсить свойство ISClient в модели вашей просмотра с помощью UIHint атрибут:

[UIHint("MyTemplate")]
public bool? IsClient { get; set; }

а потом:

 @Html.EditorFor(x => x.IsClient)

автоматически выберет пользовательский шаблон редактора.

Другие советы

Приложение для пользователей nockoutjs:

Ответ @Darin DiMitrov отличный, но немного слишком жесткий, чтобы использовать с nockoutjs, где сложные представления могут привести к просмотру, которые не совсем отображаются с параметром @Model.

Поэтому я использовал параметр opredviewData объекта. Чтобы получить доступ к параметру дополнительной проверки, из вашего пользовательского Editortemplate см. В следующем вопросе:

Доступ к дополнительным viewdata из пользовательского кода Editortemplate

Отказ: параметры дополнительного обзора сбивает с толку тем, что он ничего не делает с редактором по умолчанию. Он поступает только с помощью пользовательского шаблона редактора.

В любом случае, мои поправки к коду Дарина следующие:

@if (ViewData.ModelMetadata.IsNullableValueType) 
{
    var x = ViewData["koObservablePrefix"];
    if ((x != "") && (x != null)) { x = x + "."; }
    @Html.DropDownList(
        "", 
        triStateValues, 
        new { 
            @class = "list-box tri-state", 
            data_bind="value: " + x + ViewData.TemplateInfo.GetFullHtmlFieldName("") // or you could also use ViewData.ModelMetadata.PropertyName if you want to get only the property name and not the entire navigation hierarchy name
        }
    )
} 
else 
{
    @Html.CheckBox("", value ?? false, new { @class = "check-box" })
}

Обратите внимание на строки:

var x = ViewData["koObservablePrefix"];
if ((x != "") && (x != null)) { x = x + "."; }

KOOBServablePrefix есть, чтобы я мог добавить произвольный префикс в свой ViewModel KO.ObServable. Вы могли бы сделать другие вещи, если вы выберете.

Я использую переменную x следующим образом:

data_bind="value: " + x + ViewData.TemplateInfo.GetFullHtmlFieldName("")

Таким образом, если я не прохожу в дополнительной ревиз.

Итак, теперь я могу написать:

@Html.EditorFor(model => model.IsClient, "koBoolEditorFor", new { koObservablePrefix = "Account" })

это будет отображаться как:

<select class="list-box tri-state" data-bind="value: Account.IsBank" id="IsBank" name="IsBank">

Обратите внимание "Значение: account.isbank" Значение атрибута данных.

Это полезно, если, например, ваши представления сильно напечатаны модели типа, но в вашей учетной записи для вашей страницы у вас есть более сложная структура, поэтому вам необходимо упаковать свои наблюдаемые в объекте учетной записи. НАПРИМЕР:

function account(accountId, personId, accountName, isClient, isProvider, isBank) {

    this.AccountId   = ko.observable(accountId);
    this.PersonId    = ko.observable(personId);
    this.AccountName = ko.observable(accountName);
    this.IsClient    = ko.observable(isClient);
    this.IsProvider  = ko.observable(isProvider);
    this.IsBank      = ko.observable(isBank);
}

function accountViewModel() { 

    var self = this;

    this.selectedCostCentre = ko.observable('');            
    this.Account = new account(@Model.AccountId, @Model.PersonId, '@Model.AccountName', '@Model.IsClient','@Model.IsProvider', '@Model.IsBank');
              // etc. etc
}

Если у вас нет такой структуры, то код поднимет структуру. Это просто вопрос адаптации вашего ViewModel JS к этому, UHMMM, гибкому соглашению.

Надеюсь, это не слишком сбивает с толку ...

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top