NodeJS 使用上一个答案回答查询者中的下一个问题

kxeu7u2r  于 2022-12-03  发布在  Node.js
关注(0)|答案(2)|浏览(117)

我想用上一个答案来回答inquirer中的下一个问题,这是我的代码:

const promptForMissingOptions = async (options) => {
  const questions = [];

  if (!options.name) {
    questions.push({
      type: "input",
      name: "name",
      message: "Name:",
    });
  }

  if (!options.file) {
    questions.push({
      type: "checkbox",
      name: "lots",
      message: "Select the categories:",
      pageSize: 30,
      choices: () => {
        const files = helpers.getFileNames();
        return Object.keys(files);
      },
    });
  }

  if (answers.lots) {
    questions.push({
      type: "checkbox",
      name: "files",
      message: "Select the files:",
      pageSize: 50,
      choices: () => {
        const choices = helpers.getFileNames();
        return Object.keys(
          Object.keys(x)
            .filter((key) => answers.lots.includes(key))
            .reduce((obj, key) => {
              obj[key] = x[key];
              return obj;
            }, {})
        ).reduce(
          (r, k) =>
            r.concat(
              new inquirer.Separator(
                chalk.underline.bold.bgMagenta(
                  "------------------------ " + k + " ------------------------"
                )
              ),
              choices[k]
            ),
          []
        );
      },
    });
  }

  const answers = await inquirer.prompt(questions);

  return {
    files: options.file ? [options.file] : answers.files,
    name: options.name || answers.name,
  };
};

let options = await promptForMissingOptions(options);

我想用第二个问题的答案来回答第三个问题。
我在这里尝试了解决方案:Is there a way to use previous answers in inquirer when presenting a prompt (inquirer v6)?
但对我的案子不起作用。
我该如何解决这个问题?
先谢谢你。

v1uwarro

v1uwarro1#

在回答你的问题之前,我想指出一些对你的示例代码有帮助的优化:
您当前使用此的位置:

const questions = [];

if (!options.name) {
  questions.push({ question });
}

您可以通过以下方式实现同样的效果:

const questions = [{
  type: "input",
  name: "name",
  message: "Name:",
  when: () => options.name,
}];

来自文档的两点:

when:(函数,布尔值)接收当前用户回答的哈希值,并应返回truefalse,具体取决于是否应询问此问题。该值也可以是简单布尔值。

这里的措辞有点误导人,但这里可以归结为,当调用您分配给when的函数时,它会将 * 当前用户的答案 * 作为第一个参数传递给它,最终您的函数必须返回truefalse,以确定是否 * 应该 * 向用户显示它。

选择:(数组|函数)选择数组或返回选择数组的函数。如果定义为函数,第一个参数将是当前查询者会话的答案。[...]

下面的描述确实讨论了可能的答案值类型,但这里的关键要点是第一个函数参数:“当前查询者会话回答”。在问题3处,您可以访问问题2 * 中的答案 *。
此外,在这里我还想提出一点“个人意见”,我 * 强烈 * 建议您将依赖于Object.keys()的逻辑移出问题choices处理程序。而不是在调用时将 * 结果 * 名称数组传递给问题(即:如果该结构的任何方面发生了变化,它很可能会在其他地方发生变化;如果您在这里保留这个逻辑,那么对该逻辑的所有更改都需要更新代码中的两个位置。
现在,为了将这个概念应用到 your example questions数组中,为了简洁起见,我将使用一个应用上述概念的示例。

const promptForMissingOptions = async (options) => {
  const questions = [
    {
      type: "input",
      name: "name",
      message: "Name:",
      when: () => options.name,
    },
    {
      type: "checkbox",
      name: "lots",
      message: "Select the categories:",
      when: () => options.file,
      pageSize: 30,
      choices: () => options.categoryChoices,
    },
    {
      type: "checkbox",
      name: "files",
      message: "Select the files:",
      when: () => answers.lots.length,
      pageSize: 50,
      choices: (answers) => {
        const filteredList = [];
        const selectedCategories = answers.lots; // where the ID is the relevant question's "name".
        // now do your "filter" handling here..
        return filteredList;
      },
    },
  ];

  const answers = await inquirer.prompt(questions);

  return {
    files: options.file ? [options.file] : answers.files,
    name: options.name || answers.name,
  };
};

let options = await promptForMissingOptions(options);

我相信代码本身和问题3中的小注解在这里应该足够清楚了,但是请让我知道这是否有帮助?

k2arahey

k2arahey2#

when函数收到提示回答,并根据响应返回truefalse
因此,在可选问题中,只需将answers传递到when参数中。

const questions = [{
    name: 'REACT',
    message: 'Do you want to install React App?',
    type: 'confirm',
},
{
    name: 'EXPRESS',
    message: 'Do you want to install Express App?',
    type: 'confirm',
    when: (answers) => answers.REACT
}]

const answers = await inquirer.prompt(questions);

相关问题