-
Notifications
You must be signed in to change notification settings - Fork 1
Добавить чтение параметров #12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,128 @@ | ||
| import React, { ChangeEvent } from "react"; | ||
|
|
||
|
|
||
| type Validator<T> = {validate: (val: any) => T | undefined} | ||
|
|
||
| interface Parameter<T> { | ||
| tryParseAndSet: (str: string) => boolean; | ||
| get value(): T; | ||
| } | ||
|
|
||
| export class Num implements Parameter<number> { | ||
| _value: number; | ||
|
|
||
| get value(): number { | ||
| return this._value; | ||
| } | ||
|
|
||
| tryParseAndSet = (str: string) => { | ||
| const newValue = parseFloat(str); | ||
| if (isNaN(newValue)) { | ||
| return false; | ||
| } | ||
| this._value = newValue; | ||
| return true; | ||
| } | ||
|
|
||
| validate = (val: any) => { | ||
| if (typeof val !== 'number') { | ||
| return undefined; | ||
| } | ||
| return val; | ||
| } | ||
| } | ||
|
|
||
| export class Str implements Parameter<string> { | ||
| _value: string; | ||
| get value(): string { | ||
| return this._value; | ||
| } | ||
| tryParseAndSet = (str: string) => { | ||
| this._value = str; | ||
| return true; | ||
| } | ||
| validate = (val: any) => { | ||
| if (typeof val !== 'string') { | ||
| return undefined; | ||
| } | ||
| return val; | ||
| } | ||
| } | ||
|
|
||
| export class Arr<V, T extends Validator<V>> implements Parameter<V[]> { | ||
| _value: V[]; | ||
| _validator: T; | ||
| constructor(validator: T) { | ||
| this._validator = validator; | ||
| } | ||
| get value(): V[] { | ||
| return this._value; | ||
| } | ||
|
|
||
| tryParseAndSet = (str: string) => { | ||
| const json = JSON.parse(str); | ||
| const res = this.validate(json); | ||
| if (res === undefined) { | ||
| return false; | ||
| } | ||
| this._value = res; | ||
| return true; | ||
| } | ||
|
|
||
| validate = (val: any) => { | ||
| if (!Array.isArray(val)) { | ||
| return undefined; | ||
| } | ||
| return val.map(this._validator.validate).every(v => v !== undefined) ? val as V[] : undefined; | ||
| } | ||
| } | ||
|
|
||
| export type ParameterProps<T> = { | ||
| label: string, | ||
| value: Parameter<T> | ||
| } | ||
|
|
||
| export type State<T> = { | ||
| value: Parameter<T>, | ||
| error: boolean | ||
| } | ||
|
|
||
| export class ParameterComponent<T> extends React.Component<ParameterProps<T>, State<T>> { | ||
| label: string; | ||
| constructor(prop: ParameterProps<T>) { | ||
| super(prop); | ||
| this.label = prop.label; | ||
| this.state = { | ||
| value: prop.value, | ||
| error: false, | ||
| } | ||
| } | ||
|
|
||
| onChange(event: ChangeEvent<HTMLInputElement>) { | ||
| console.log(this) | ||
| try { | ||
| this.setState({ | ||
| value: this.state.value, | ||
| error: !this.state.value.tryParseAndSet(event.target.value), | ||
| }) | ||
| } catch { | ||
| this.setState({ | ||
| value: this.state.value, | ||
| error: true, | ||
| }) | ||
| } | ||
| } | ||
|
|
||
| render(): React.ReactNode { | ||
| return <div>{this.label}: <input onChange={(e) => this.onChange(e)}/> {this.state.error && "invalid value"}</div> | ||
| } | ||
|
|
||
| } | ||
|
|
||
| // export const ParametersComponent = <T, >(object: Parameter<T>) => { | ||
| // return <input onChange={object.tryParseAndSet}></input> | ||
| // const c = new Arr(new Arr(new Num())) | ||
| // console.log(c) | ||
| // console.log(c.tryParseAndSet("[[1], [2], [3]]")) | ||
| // console.log(c) | ||
| // } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,12 +1,22 @@ | ||
| import { ParameterComponent, Num, Arr } from "../../lib/params" | ||
| import { BubbleSortArguments } from "./bubble-sort" | ||
|
|
||
| // type Props = { | ||
| // doStart: (args: BubbleSortArguments, noStop: boolean) => void | ||
| // } | ||
|
|
||
| export const BubbleSortStarter = ({ doStart }) => { | ||
|
|
||
| const propArr = { | ||
| label: "массив", | ||
| value: new Arr<number, Num>(new Num()) | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Семантически непонятно - зачем передавать сначала number - тип, а потом Num - класс который по сути боксит значение при валидации |
||
| } | ||
|
|
||
| const components = [<ParameterComponent<number[]> {...propArr} />].map((v) => <li>{v}</li>); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Если честно, то такая конструкция мне немного режет глаза :) |
||
|
|
||
| return <div> | ||
| <button onClick={() => doStart([[5, 4, 3, 2, 1]], false)}>Start</button> | ||
| <button onClick={() => doStart([[5, 4, 3, 2, 1]], true)}>Run Full</button> | ||
| <ul>{components}</ul> | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Когда рисуешь список компонентов каждому нужно указывать key=... |
||
| <button onClick={() => doStart([propArr.value.value], false)}>Start</button> | ||
| <button onClick={() => doStart([propArr.value.value], true)}>Run Full</button> | ||
| </div>; | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Классовые компоненты - зло.
Давай перепишем на функциональные?
А ещё кажется что это не должно быть в lib
в lib скорее должно быть всё что нужно для алгоритмов
Давай компоненты для отрисовки вынесем в папочку components и будем делать по одному семантически важному компоненту в файле?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Да, парадигма реакта сложная
Но в то же время достаточно простая и минималистичная.
Нужно просто немного по-другому думать.
Если нужно - я могу это доделать
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.