Repeating Prompts with a Yeoman Generator

江枫思渺然 提交于 2019-12-12 09:18:13

问题


I am creating a Yeoman Generator to automate creation of few database tables. I need to provide users with a prompt to add multiple columns (combination of ColumnName and DataType below).

I have a template saved in my disk where I bind the dynamic names from the user inputs and based upon this template, the final script is generated by the Yeoman Generator. Can you suggest how to prompt user to enter repetitive combinations of ColumnName/DataType he wants to enter?

var prompts = [{
    type: 'input',
    name: 'name',
    message: 'The Table Name?'
  }, {
    type: 'input',
    name: 'attributeName',
    message: 'Define your Schema - ColumnName?',
    default: 'ID'
  },{
    type: 'input',
    name: 'attributeType',
    message: 'Define your Schema - DataType?',
    default: 'S'
  }
];


  return this.prompt(prompts).then(function (props) {
    this.props = props;
  }.bind(this));

Template content -- User can enter details of 1/2/3/4 or more columns and once he does that the template below should be intelligent enough to create that many column key combinations.

{
  "Type" : "AWS::Table",
  "Properties" : {
    "AttributeDefinitions" :  
          {
            "AttributeName" : "<%= attributeName %>",
            "AttributeType" : "<%= attributeType %>"
          },
          {
            "AttributeName" : "<%= attributeName %>",
            "AttributeType" : "<%= attributeType %>"
          },
    "TableName" : <%= name %>,

    }
}

回答1:


You can add a recursive function inside the prompting() hook. It has to be made sure that the recursive function returns this.prompts else the execution might stop.

My strategy works like below

  • Declare a recursive function that repeats based on one of the input

  • Populate the props as you recurse through in this.columns

  • Pass this instance variable to the template in writing() hook

  • Iterate over the this.columns in the template and populate your columns

  • First entry in this.columns will have the table name and the first column details

Check the code below, you can tweak this to your needs as long as the recursive function is invoked as expected.

There is an extra prompt that asks whether to repeat or not. It can also be discarded with some logic but that is up to you.

prompting()

prompting() {
  // Have Yeoman greet the user.
  this.log(yosay(
    'Welcome to the remarkable ' + chalk.red('generator-react-starter-kit-relay-container') + ' generator!'
  ));

  const tableNamePrompt = [{
    type: 'input',
    name: 'name',
    message: 'The Table Name?'
  }];

  const columnPrompts = [{
    type: 'input',
    name: 'attributeName',
    message: 'Define your Schema - ColumnName?',
    default: 'ID'
  }, {
    type: 'input',
    name: 'attributeType',
    message: 'Define your Schema - DataType?',
    default: 'S'
  }, {
    type: 'confirm',
    name: 'repeat',
    message: 'Do you want to add more columns?',
    default: 'Y'
  }]

  this.columns = [];

  const loop = (relevantPrompts) => {
    return this.prompt(relevantPrompts).then(props => {
      this.columns.push(props);

      return props.repeat ? loop(columnPrompts) : this.prompt([]);

    })
  }

  return loop([...tableNamePrompt, ...columnPrompts]);
}

And then in the writing() hook pass the columns instance variable that you populated earlier.

writing()

writing() {
  this.fs.copyTpl(
    this.templatePath('Schema.json'),
    this.destinationPath('./Schema.json'),
    {
      columns: this.columns
    }
  );
}

TEMPLATE

{
  "Type" : "AWS::Table",
  "Properties" : {
    "AttributeDefinitions" : [
      <% for (let i=0; i<columns.length; i++) { %>
        {
          "AttributeName": "<%= columns[i].attributeName %>",
          "AttributeType": "<%= columns[i].attributeType %>"
        }
      <% } %>
    ],
    "TableName" : "<%= (columns[0] || {}).name %>"
  }
}

SAMPLE INPUT

     _-----_     ╭──────────────────────────╮
    |       |    │      Welcome to the      │
    |--(o)--|    │        remarkable        │
   `---------´   │ generator-react-starter- │
    ( _´U`_ )    │    kit-relay-container   │
    /___A___\   /│        generator!        │
     |  ~  |     ╰──────────────────────────╯
   __'.___.'__   
 ´   `  |° ´ Y ` 

? The Table Name? User
? Define your Schema - ColumnName? ID
? Define your Schema - DataType? Bigint
? Do you want to add more columns? Yes
? Define your Schema - ColumnName? Email
? Define your Schema - DataType? String
? Do you want to add more columns? Yes
? Define your Schema - ColumnName? Password
? Define your Schema - DataType? Text
? Do you want to add more columns? No

OUTPUT

{
  "Type" : "AWS::Table",
  "Properties" : {
    "AttributeDefinitions" : [

        {
          "AttributeName": "ID",
          "AttributeType": "Bigint"
        }

        {
          "AttributeName": "Email",
          "AttributeType": "String"
        }

        {
          "AttributeName": "Password",
          "AttributeType": "Text"
        }

    ],
    "TableName" : "User"
  }
}


来源:https://stackoverflow.com/questions/48634349/repeating-prompts-with-a-yeoman-generator

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!