如何在 JavaScript 中实现步进决策流程?
How to implement a stepper decision flow in JavaScript?
我实际上不确定我要描述的内容的最佳名称。决策流程、决策矩阵、流程图...
实现基本上是 "Choose Your Own Adventure" 步进器或流程图变成步进器的流程的最佳方法是什么?
例如,您有一个带有步骤的 UI,将出现的下一步和上一步取决于上一步的数据。现在,我有一个 switch 语句来确定要出现的步骤,以及用于确定下一步或上一步的非常丑陋的逻辑。
(我正在使用 React 为每个步骤渲染组件,但我认为这对这个问题来说并不重要)。
renderStep = () => {
switch (currentStep) {
case 1:
return <FirstStep/>
case 2:
return <SecondStep />
case 2.5:
return <SecondStepA />
case 3:
return <ThirdStep />
case 3.25:
return <ThirdStepA />
case 3.5:
return <ThirdStepB />
case 3.75:
return <ThirdStepC />
case 4:
return <FourthStep />
default:
return null
}
}
现在点击"Next"或"Previous"将发送数据,并确定每一步要进行的步骤。如果流程是线性的,那将非常容易——更新数据,递增或递减 1。但是有了条件流程,就变得更复杂了。
goToPreviousStep = () => {
const { currentStep } = this.state
this.setState(prevState => {
if (currentStep === 4 && prevState.someDataHappened) {
return { currentStep: prevState.currentStep - 0.5 }
} else if (currentStep === 3.5) {
return { currentStep: prevState.currentStep - 0.5 }
} else {
return { currentStep: prevState.currentStep - 1 }
}
})
}
可能尝试支持额外的嵌套会更加复杂。随着它的增长,我知道它会变得无法维护,但我找不到任何好的资源来将这些数据存储在 table 或其他东西中以使其更具编程性。有人能指出我正确的方向吗?
不确定我是否必须编写一些非确定性有限自动机或其他东西...
你看过类似于链表工作原理的东西吗?每个步骤都是一个 object,并且每个步骤都有对其上一步以及可能的后续步骤的引用。可以通过这些链接进行遍历,当前步骤可以存储为 object 而不是某种数字。如果你想给它们编号,你可以简单地计算所有的步骤,然后向后遍历到第一步,看看你在第几步。
您可以在 Step 原型中放置所需的数据,以便每个步骤都定义呈现它、根据它采取操作等所需的一切。标题、文本、关联的 url 等。
function Step() {}
Step.prototype.previous = null;
Step.prototype.next = [];
Step.prototype.addNext = function(nextStep) {
let step = Object.assign(new Step(), nextStep);
step.previous = this;
this.next.push(step);
}
Step.prototype.getNumber = function() {
var number = 0;
var step = this;
while(step) {
step = step.previous;
number += 1;
}
return number;
}
let CurrentStep = null;
function createSteps() {
const step1 = new Step();
const step2 = new Step();
const step2_1 = new Step();
const step2_2 = new Step();
const step3 = new Step();
CurrentStep = step1;
step1.addNext(step2);
step1.addNext(step2_1);
step1.addNext(step2_2);
step2.addNext(step3);
step2_1.addNext(step3);
step2_2.addNext(step3);
}
createSteps();
console.log(CurrentStep.getNumber());
console.log(CurrentStep.next[0].getNumber());
console.log(CurrentStep.next[1].getNumber());
console.log(CurrentStep.next[2].getNumber());
我实际上不确定我要描述的内容的最佳名称。决策流程、决策矩阵、流程图...
实现基本上是 "Choose Your Own Adventure" 步进器或流程图变成步进器的流程的最佳方法是什么?
例如,您有一个带有步骤的 UI,将出现的下一步和上一步取决于上一步的数据。现在,我有一个 switch 语句来确定要出现的步骤,以及用于确定下一步或上一步的非常丑陋的逻辑。
(我正在使用 React 为每个步骤渲染组件,但我认为这对这个问题来说并不重要)。
renderStep = () => {
switch (currentStep) {
case 1:
return <FirstStep/>
case 2:
return <SecondStep />
case 2.5:
return <SecondStepA />
case 3:
return <ThirdStep />
case 3.25:
return <ThirdStepA />
case 3.5:
return <ThirdStepB />
case 3.75:
return <ThirdStepC />
case 4:
return <FourthStep />
default:
return null
}
}
现在点击"Next"或"Previous"将发送数据,并确定每一步要进行的步骤。如果流程是线性的,那将非常容易——更新数据,递增或递减 1。但是有了条件流程,就变得更复杂了。
goToPreviousStep = () => {
const { currentStep } = this.state
this.setState(prevState => {
if (currentStep === 4 && prevState.someDataHappened) {
return { currentStep: prevState.currentStep - 0.5 }
} else if (currentStep === 3.5) {
return { currentStep: prevState.currentStep - 0.5 }
} else {
return { currentStep: prevState.currentStep - 1 }
}
})
}
可能尝试支持额外的嵌套会更加复杂。随着它的增长,我知道它会变得无法维护,但我找不到任何好的资源来将这些数据存储在 table 或其他东西中以使其更具编程性。有人能指出我正确的方向吗?
不确定我是否必须编写一些非确定性有限自动机或其他东西...
你看过类似于链表工作原理的东西吗?每个步骤都是一个 object,并且每个步骤都有对其上一步以及可能的后续步骤的引用。可以通过这些链接进行遍历,当前步骤可以存储为 object 而不是某种数字。如果你想给它们编号,你可以简单地计算所有的步骤,然后向后遍历到第一步,看看你在第几步。
您可以在 Step 原型中放置所需的数据,以便每个步骤都定义呈现它、根据它采取操作等所需的一切。标题、文本、关联的 url 等。
function Step() {}
Step.prototype.previous = null;
Step.prototype.next = [];
Step.prototype.addNext = function(nextStep) {
let step = Object.assign(new Step(), nextStep);
step.previous = this;
this.next.push(step);
}
Step.prototype.getNumber = function() {
var number = 0;
var step = this;
while(step) {
step = step.previous;
number += 1;
}
return number;
}
let CurrentStep = null;
function createSteps() {
const step1 = new Step();
const step2 = new Step();
const step2_1 = new Step();
const step2_2 = new Step();
const step3 = new Step();
CurrentStep = step1;
step1.addNext(step2);
step1.addNext(step2_1);
step1.addNext(step2_2);
step2.addNext(step3);
step2_1.addNext(step3);
step2_2.addNext(step3);
}
createSteps();
console.log(CurrentStep.getNumber());
console.log(CurrentStep.next[0].getNumber());
console.log(CurrentStep.next[1].getNumber());
console.log(CurrentStep.next[2].getNumber());