Вариант выбора DevExtreme со словарем

Я пытаюсь заполнить DevExtreme SelectBox() (или Lookup()) с помощью Dictionary<string><string>, но получаю сообщение об ошибке:

Неперехваченная ошибка: E4006 — параметр «данные» ArrayStore должен быть массивом.

Модель

public string Lang { get; set; }
public Dictionary<string, string> Languages { get; }

...

this.Lang = "es";

this.Languages = new Dictionary<string, string>() { {"en", "English"},  {"ar", "Arabic"},     {"bn", "Bengali"},   {"cs", "Czech"},      {"da", "Danish"},    {"de", "German"},
                                                    {"el", "Greek"},    {"es", "Spanish"},    {"fa", "Persian"},   {"fi", "Finnish"},    {"fil", "Filipino"}, {"fr", "French"},
                                                    {"he", "Hebrew"},   {"hi", "Hindi"},      {"hu", "Hungarian"}, {"id", "Indonesian"}, {"it", "Italian"},   {"ja", "Japanese"},
                                                    {"ko", "Korean"},   {"msa", "Malay"},     {"nl", "Dutch"},     {"no", "Norwegian"},  {"pl", "Polish"},    {"pt", "Portuguese"},
                                                    {"ro", "Romanian"}, {"ru", "Russian"},    {"sv", "Swedish"},   {"th", "Thai"},       {"tr", "Turkish"},   {"uk", "Ukrainian"},
                                                    {"ur", "Urdu"},     {"vi", "Vietnamese"}, {"zh-cn", "Chinese (Simplified)"},         {"zh-tw", "Chinese (Traditional)"} };

Просмотреть

@(Html.DevExtreme().Form()
        .ID("form")
        .FormData(Model)
        .ColCount(12)
        .ShowValidationSummary(true)
        .Items(i =>
        {
            i.AddSimple()
            .ColSpan(6)
            .Label(l => l.Visible(false))
            .DataField(Model.Lang.ToString())
            .Editor(ed => ed.SelectBox()
                            .DataSource(Model.Languages)
                            .Placeholder("Language..."));
        }))

Я пытался сделать List, который не возвращает ошибку, но ничего не показывает.

Модель

public string Lang { get; set; }
public Dictionary<string, string> Languages { get; }
public List<Dictionary<string, string>> List { get; }

...

this.Lang = "es";

this.Languages = new Dictionary<string, string>() { {"en", "English"},  {"ar", "Arabic"},     {"bn", "Bengali"},   {"cs", "Czech"},      {"da", "Danish"},    {"de", "German"},
                                                    {"el", "Greek"},    {"es", "Spanish"},    {"fa", "Persian"},   {"fi", "Finnish"},    {"fil", "Filipino"}, {"fr", "French"},
                                                    {"he", "Hebrew"},   {"hi", "Hindi"},      {"hu", "Hungarian"}, {"id", "Indonesian"}, {"it", "Italian"},   {"ja", "Japanese"},
                                                    {"ko", "Korean"},   {"msa", "Malay"},     {"nl", "Dutch"},     {"no", "Norwegian"},  {"pl", "Polish"},    {"pt", "Portuguese"},
                                                    {"ro", "Romanian"}, {"ru", "Russian"},    {"sv", "Swedish"},   {"th", "Thai"},       {"tr", "Turkish"},   {"uk", "Ukrainian"},
                                                    {"ur", "Urdu"},     {"vi", "Vietnamese"}, {"zh-cn", "Chinese (Simplified)"},         {"zh-tw", "Chinese (Traditional)"} };

this.List = new List<Dictionary<string, string>>() { this.Languages };

Просмотреть

@(Html.DevExtreme().Form()
        .ID("form")
        .FormData(Model)
        .ColCount(12)
        .ShowValidationSummary(true)
        .Items(i =>
        {
            i.AddSimple()
            .ColSpan(6)
            .Label(l => l.Visible(false))
            .DataField(Model.Lang.ToString())
            .Editor(ed => ed.SelectBox()
                            .DataSource(Model.List)
                            .Placeholder("Language..."));
        }))

ВыбратьЯщик()


person Andrés Marotta    schedule 23.10.2018    source источник


Ответы (2)


Опция ArrayStore 'data' должна быть массивом указывает, что вы не передаете правильный объект (т. е. объект массива) в источник данных SelectBox (обратите внимание, что Dictionary<string, string> нельзя напрямую преобразовать в одномерный массив требуется dataSource объектом).

В случае, если это DevExtreme в ASP.NET MVC, вы можете попробовать создать базовый класс модели для списка языков следующим образом:

public class Language
{
    public string LangID { get; set; }

    public string LangName { get; set; }
}

Обратите внимание, что необходимо иметь свойство List<Language> в целевой модели представления, например. List<Language> Languages { get; set; }. Затем создайте список языков, как в примере ниже:

Действие контроллера

this.Lang = "es";

this.Languages = new List<Language>() {
                     new Language { LangID = "en", LangName = "English" },
                     new Language { LangID = "el", LangName = "Greek" },
                     // other language definitions
                 };

// convert to JSON format and return this into view
this.LangArray = JsonConvert.SerializeObject(this.Languages);

Просмотреть

@(Html.DevExtreme().Form()
        .ID("form")
        .FormData(Model)
        .ColCount(12)
        .ShowValidationSummary(true)
        .Items(i =>
        {
            i.AddSimple()
            .ColSpan(6)
            .Label(l => l.Visible(false))
            .DataField(Model.Lang.ToString())
            .Editor(ed => ed.SelectBox()
                            .DataSource(Model.LangArray)
                            .DisplayExpr("LangName") // displayed text
                            .ValueExpr("LangID") // selected value for submit
                            .Placeholder("Language..."));
        }))

Дополнительное примечание:

Если вы все еще хотите использовать Dictionary, убедитесь, что вы преобразовали его в строку, соответствующую формату пары "ключ-значение" JSON:

public static string ToJsonArray(this Dictionary<string, string> dict)
{
    var kvp = dict.Select(x => string.Format(@"""{0}"":""{1}""", x.Key, string.Concat(",", x.Value)));
    return string.Concat("{", string.Join(",", kvp), "}");
}

// Usage
this.LangArray = this.Languages.ToJsonArray();

Использованная литература:

Справочник по API DataSource

Справочник по API SelectBox

Пример SelectBox

person Tetsuya Yamamoto    schedule 23.10.2018
comment
Я нашел обходной путь. Не красиво, но с меньшими изменениями. Все равно спасибо! - person Andrés Marotta; 23.10.2018

Я смог решить эту проблему с помощью Linq, создав массив на лету:

i.AddSimple()
    .ColSpan(6)
    .Label(l => l.Visible(false))
    .DataField(Model.Lang)
    .Editor(ed => ed.SelectBox()
                    .DataSource(ds => ds.Array().Key("value").Data(Model.Languages.Select(s => new { value = s.Key, text = s.Value })))
                    .Value(Model.Lang)
                    .ValueExpr("value")
                    .DisplayExpr("text")
                    .Placeholder("Language..."));
person Andrés Marotta    schedule 23.10.2018
comment
Кроме того, в DataField вы хотите передать имя поля, а не значение, поэтому .DataField("Lang"). Тогда вам больше не нужен .Value(Model.Lang). - person Rafał Rutkowski; 25.10.2018