botbuilder v 4, динамическая адаптивная карта с выпадающим списком и вводом значений по запросу - PullRequest
0 голосов
/ 08 января 2019

Я использую MS Botbuilder V 4 Я использую webcontrol, webchat.js, последние, реагируют Дело довольно тривиально: Я хочу показать список возможных значений в раскрывающемся списке, значения будут динамическими (поступает из API, мне нужны там заголовки и значения (идентификаторы). Затем, когда пользователь выбирает какой-то элемент и нажимает кнопку ОК, я хочу получить значение (идентификатор) и работать дальше с этим. Пока я понял, что единственный способ показать, что выпадающий список - это использование адаптивных карт, в v3 была возможность использовать адаптивные карты в приглашениях, и это также запланировано для следующей версии: https://github.com/Microsoft/botbuilder-dotnet/issues/1170 Но пока здесь объясняется только то, что нужно: https://github.com/Microsoft/botbuilder-dotnet/issues/614, только со списком строк все работает нормально, но если я хочу сохранить пары значений ключей (для идентификаторов), я не могу этого сделать, потому что Choices в PromptOptions принимает только список строк (будет показано ниже) , Таким образом, единственное временное решение, которое я использую сейчас, - это сохранить всю коллекцию значений и после получения результата пойти и найти его идентификатор. Есть ли более удобное решение для этого? Вот код:

var choicesInputs = _teams.Select(s => new AdaptiveChoice { Title = s.Value, Value = s.Value}).ToList();

var card = new AdaptiveCard
{
    Version = new AdaptiveSchemaVersion(1, 0),
    Body =
    {
        new AdaptiveTextBlock("Select a team to assign your ticket"),
        new AdaptiveChoiceSetInput
        {
            Choices = choicesInputs,
            Id = "setId",
            Style = AdaptiveChoiceInputStyle.Compact,
            IsMultiSelect = false
        }
    },
    Actions = new List<AdaptiveAction>
    {
        new AdaptiveSubmitAction
        {
            Title = "Ok",
            Type = "Action.Submit"
        }
    }
};

signInPhoneState.Teams = _teams;

return await stepcontext.PromptAsync(
    "SelectGroupCardDialog",
    new PromptOptions
    {
            Choices = ChoiceFactory.ToChoices(_teams.Select(pair => pair.Value).ToList()),
        Prompt = (Activity) MessageFactory.Attachment(new Attachment
        {
            ContentType = AdaptiveCard.ContentType,
            Content = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(card))
        })
    },
    cancellationtoken);

// . . .

var selectedTeamId = signInPhoneState.Teams.FirstOrDefault(pair => pair.Value == sel).Key;

Быстрый побочный вопрос (но связанный с тем, что я использую его для обхода проблемы): Какой самый простой способ сохранить некоторую переменную через диалог? Если я правильно помню, в v3 это было так же просто, как пометить значение как public и пометить диалог как сериализуемый, и все, теперь, когда я его получил, вам нужно создать специальный аксессор для каждого диалога, дублировать свойство и управлять его состоянием, это правильно? Спасибо

1 Ответ

0 голосов
/ 09 февраля 2019

У вас есть словарь с идентификаторами команд в качестве ключей и именами команд в качестве значений. Вы используете имена команд в качестве значений для адаптивного набора выбора, который используется в приглашении, и, в свою очередь, после запроса вы извлекаете идентификатор команды из словаря, используя имя команды. Вы хотите более удобный вариант.

Вариант 1. Если вы согласны с текущими настройками сохранения словаря

При доступе к данным в словаре доступ к значению с помощью ключа более эффективен, чем наоборот. Это то, для чего словари, в конце концов. Таким образом, вместо использования названий команд в качестве значений в выбранном наборе, вы можете использовать идентификаторы команд.

var choicesInputs = _teams.Select(s => new AdaptiveChoice { Title = s.Value, Value = s.Key }).ToList();

// . . .

signInPhoneState.Teams.TryGetValue(sel, out string selectedTeamName);

Это будет означать, что если словарь создается из какого-либо внешнего источника, который может быть изменен, название команды будет как можно более актуальным.

Вариант 2: если вы не хотите зависеть от словаря для следующего хода

Вы можете сохранить как идентификатор команды, так и название команды в значении выбора.

var choicesInputs = _teams.Select(s => new AdaptiveChoice { Title = s.Value, Value = JsonConvert.SerializeObject(s) }).ToList();

// . . .

var pair = JsonConvert.DeserializeObject<KeyValuePair<string, string>>(sel);
var selectedTeamId = pair.Key;
var selectedTeamName = pair.Value;

Это будет означать, что если базовые данные изменятся между первым поворотом приглашения и вторым, выбор все равно будет действительным.

...