【问题标题】:How to change the value of input dynamically?如何动态改变输入的值?
【发布时间】:2019-09-14 19:13:22
【问题描述】:

我有一个动态输入,我可以添加和删除一行输入,有用于 timepicker 的 material-ui 输入,当我点击它时,它有一个带有时钟图标的输入,时钟会出现。但是这个输入的值不能随时钟变化。

我的代码是:

import { TimePicker } from "material-ui-time-picker";
import {
  Input as Time,
  Dialog as Clock,
  DialogActions,
  Button as ButtonOk
} from "@material-ui/core";
  constructor(props) {
    super(props);
    this.state = {
      isOpenS: false,
      isOpenE: false,
      start: moment().format("HH:MM"),
      end: moment().format("HH:MM"),
      tranches: [
        { start: moment().format("HH:MM"), end: moment().format("HH:MM") }
      ]
    };

    this.ajouterTranche = this.ajouterTranche.bind(this);
    this.supprimerTranche = this.supprimerTranche.bind(this);
    this.handleKeyboardStartChange = this.handleKeyboardStartChange.bind(this);
  }


  openDialogS = () => this.setState({ isOpenS: true });
  closeDialogS = () => this.setState({ isOpenS: false });
  backdropClickS = () => this.setState({ isOpenS: false });
  handleDialogStartChange = (i, newValue) => {
    const hours = newValue
      .getHours()
      .toString()
      .padStart(2, "0");
    const minutes = newValue
      .getMinutes()
      .toString()
      .padStart(2, "0");
    const textValue = hours + ":" + minutes;
    // this.setState({ start: textValue });
    this.state.tranches[i] = Object.assign({}, this.state.tranches[i], {
      start: textValue
    });
    this.setState({
      tranches: this.state.tranches
    });
  };

  handleKeyboardStartChange = (i, event) => {
    const rowDataCopy = this.state.tranches.slice(0);
    rowDataCopy[i] = Object.assign({}, rowDataCopy[i], {
      start: event.target.value
    });
    this.setState({
      tranches: rowDataCopy
    });
  };
  createDateFromTextValue = (i, value) => {
    const splitParts = value.split(":");
    return new Date(1970, 1, 1, splitParts[0], splitParts[1]);
  };

  openDialogE = () => this.setState({ isOpenE: true });
  closeDialogE = () => this.setState({ isOpenE: false });
  handleDialogEndChange = newValue => {
    const hours = newValue
      .getHours()
      .toString()
      .padStart(2, "0");
    const minutes = newValue
      .getMinutes()
      .toString()
      .padStart(2, "0");
    const textValue = hours + ":" + minutes;
    this.setState({ end: textValue });
  };
  handleKeyboardEndChange = (i, event) => {
    // On va copier le tableau de tranches
    const rowDataCopy = this.state.tranches.slice(0);
    // On va jouter cette valeur changée au tableau de tranches
    rowDataCopy[i] = Object.assign({}, rowDataCopy[i], {
      end: event.target.value
    });
    this.setState({
      tranches: rowDataCopy
    });
  };
  createDateFromTextValue = value => {
    const splitParts = value.split(":");
    return new Date(1970, 1, 1, splitParts[0], splitParts[1]);
  };


  ajouterTranche = () => {
    this.setState(prevState => ({
      tranches: [...prevState.tranches, ""]
    }));
  };

  supprimerTranche = idx => () => {
    const rowDataCopy = this.state.tranches.slice(0);
    rowDataCopy.splice(1, 1);
    this.setState({
      tranches: rowDataCopy
    });
  };
render() {

    console.log(this.state.start);
    return (

      <div>
        {this.state.tranches.map((el, i) => (
          <Row key={i}>
            <Col span={12} />
            <Col span={12}>
              <Row>
                <Col span={8}>
                  &nbsp; &nbsp; &nbsp;
                  <label className="pt-label .modifier">
                    <strong>Heure de début</strong>
                  </label>
                  <br />
                  <Time
                    value={el.start}
                    onChange={time => this.handleKeyboardStartChange(i, time)}
                    style={heure}
                    disableUnderline={true}
                    inputComponent={TextMaskCustom}
                    endAdornment={
                      <InputAdornment position="end" style={{ opacity: "0.4" }}>
                        <IconButton onClick={this.openDialogS}>
                          <AccessTime />
                        </IconButton>
                      </InputAdornment>
                    }
                  />
                  <Clock
                    maxWidth="xs"
                    open={this.state.isOpenS}
                    onBackdropClick={this.closeDialogS}
                  >
                    <TimePicker
                      mode="24h"
                      value={this.createDateFromTextValue(this.state.start)}
                      onChange={time => this.handleDialogStartChange(i, time)}
                    />
                    <DialogActions>
                      <ButtonOk onClick={this.closeDialogS} color="primary">
                        Ok
                      </ButtonOk>
                    </DialogActions>
                  </Clock>
                  <br />
                </Col>
                <Col span={8}>
                  &nbsp; &nbsp; &nbsp;
                  <label className="pt-label .modifier">
                    <strong>Heure de fin</strong>
                  </label>
                  <br />
                  <Time
                    value={el.end}
                    onChange={time => this.handleKeyboardEndChange(i, time)}
                    style={heure}
                    disableUnderline={true}
                    inputComponent={TextMaskCustom}
                    endAdornment={
                      <InputAdornment position="end" style={{ opacity: "0.4" }}>
                        <IconButton onClick={this.openDialogS}>
                          <AccessTime />
                        </IconButton>
                      </InputAdornment>
                    }
                  />
                  <Clock
                    maxWidth="xs"
                    open={this.state.isOpenE}
                    onBackdropClick={this.closeDialogE}
                  >
                    <TimePicker
                      mode="24h"
                      value={this.createDateFromTextValue(this.state.end)}
                      onChange={this.handleDialogEndChange}
                    />
                    <DialogActions>
                      <ButtonOk onClick={this.closeDialogE} color="primary">
                        Ok
                      </ButtonOk>
                    </DialogActions>
                  </Clock>
                  <br />
                </Col>
                <Col span={8}>
                  {i === 0 ? (
                    <>
                      <br />
                      &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
                      &nbsp;
                      <Icon
                        type="plus-circle"
                        theme="twoTone"
                        twoToneColor="#52c41a"
                        onClick={this.ajouterTranche}
                      />
                      <br />
                    </>
                  ) : (
                    <>
                      <Icon
                        type="close-circle"
                        theme="twoTone"
                        twoToneColor="red"
                        onClick={this.supprimerTranche(i)}
                      />
                      <Icon
                        type="plus-circle"
                        theme="twoTone"
                        twoToneColor="#52c41a"
                        onClick={this.ajouterTranche}
                      />
                      <br />
                    </>
                  )}
                </Col>
              </Row>
            </Col>
          </Row>
        ))}
      </div>


    );
  }
}

我的沙盒代码是:https://codesandbox.io/s/182oy5995l

当我在输入上输入一个值并单击时钟时,我得到时钟的时刻值,而不是我在输入上输入的值。 我希望当我从时钟更改时间时,输入会发生变化,反之亦然。

我该如何解决?

【问题讨论】:

    标签: javascript reactjs input material-ui onchange


    【解决方案1】:

    解决 我得到了时钟,我选择了小时,但它没有改变value={el.start} 稍微更改为 value= {this.state.start}

    【讨论】:

    • 但是,当我创建value={this.state.start}时,所有行的输入都是相同的值
    【解决方案2】:

    我会让你走上正轨。我想如果你得到了这个,你将能够快速解决剩下的问题。不过,我真的不知道您要对开始和结束做什么。所以我所做的只能在时间选择器上工作,你可以用它来修复键盘。

    这是我的分叉版本
    https://codesandbox.io/s/2xm39130kn

    当您使用多个对象调用handleDialogStartChange 时,您不能只修改一个状态。除非他们都应该共享同一时间。这似乎毫无意义。

    我将你的 timepicker onChange 函数修改为 onChange={time =&gt; this.handleDialogStartChange(i, time)},这样你也可以推送索引,以便知道要使用哪个索引。

    我将您的 timepicker 值函数修改为 value={this.createDateFromTextValue(el.start)},因此您引用的是单个元素,而不是原始状态变量。

    然后在andleDialogStartChange 中使用该索引修改您存储这些时间的批次的状态。你会得到一个警告,不要像这样修改状态,但只要你将它与 setState 结合使用,this.setState({ tranches: this.state.tranches });,这是一个合法的操作。

    handleDialogStartChange = (i, newValue) => {
        const hours = newValue
          .getHours()
          .toString()
          .padStart(2, "0");
        const minutes = newValue
          .getMinutes()
          .toString()
          .padStart(2, "0");
        const textValue = hours + ":" + minutes;
        this.state.tranches[i].start = textValue;
        this.state.tranches[i].end = textValue;
        this.setState({ tranches: this.state.tranches });
        this.setState({ start: textValue });
      };
    

    【讨论】:

    • start 是 start 的输入,end 是另一个输入,当我点击 plus 时,会添加一行 start 和 end 的输入
    • end 应该是您刚刚更改的任何内容?
    • 试用沙盒并告诉我什么不符合您的预期?
    • 当我在输入上输入一个值并单击时钟时,我得到时钟的时刻值,而不是我输入的值。我想当我从时钟改变时间时,输入会改变,反之亦然。 codesandbox.io/s/182oy5995l
    • 我不确定您做了什么更改,现在对话框将最后创建的行的值拉入时间选择器。我不知道如何解决。这是我当前的版本,这是我认为唯一不起作用的版本。 codesandbox.io/s/mznj5nkopp
    猜你喜欢
    • 2019-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-12
    • 1970-01-01
    • 2012-12-14
    • 2020-05-30
    • 2021-09-27
    相关资源
    最近更新 更多