无论我做什么,为什么这个子对象为空?

时间:2019-05-25 13:53:25

标签: javascript reactjs meteor meteor-collection2

我正在为此抓挠头。

尝试:

Reservation.insert(this.state);

const res = //手动设置每个字段

const res = //手动设置每个字段以及设置parkingLot字段,如代码中所示

我不知道我还能尝试什么,res.parkingLot始终保持为空对象。尝试插入时会导致错误。

完整功能在这里:

handleSubmit(event, $) {
  event.preventDefault();

  const res = {
    date: new Date(),
    parkingLot: {
      _id: this.state.parkingLot._id,
      number: this.state.parkingLot.number,
      name: this.state.parkingLot.name,
      description: this.state.parkingLot.description,
      price: this.state.parkingLot.price,
      reserved: this.state.parkingLot.reserved,
    },
    user: $.state.user,
    begin: $.state.begin,
    end: $.state.end,
  };

  console.log('Submit', res, this.state);

  Reservation.insert(res);
}

系统要求我添加整个代码,

ReservationForm.js

import React, {Component} from 'react';
import {Reservation} from "../../../shared/collections/Reservation";
import {withTracker} from "meteor/react-meteor-data";
import {ParkingLot} from "../../../shared/collections/ParkingLot";
import MaterialSelect from "../form/MaterialSelect";
import * as M from "materialize-css";

class ReservationForm extends Component {
    constructor(props) {
        super(props);
        this.state = {};

        this.handleInputChange = this.handleInputChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.handleBeginPicker = this.handleBeginPicker.bind(this);
        this.handleEndPicker = this.handleEndPicker.bind(this);
    }

    componentDidMount() {
        let beginPicker = document.querySelector('#begin');
        let endPicker = document.querySelector('#end');
        M.Datepicker.init(beginPicker, {
            autoClose: true,
            onSelect: this.handleBeginPicker
        });
        M.Datepicker.init(endPicker, {
            autoClose: true,
            onSelect: this.handleEndPicker
        });
    }

    handleBeginPicker(date) {
        const event = {
            target: {
                name: 'begin',
                value: date
            }
        };

        this.handleInputChange(event);
    }

    handleEndPicker(date) {
        const event = {
            target: {
                name: 'end',
                value: date
            }
        };

        this.handleInputChange(event);
    }

    handleInputChange(event) {
        const target = event.target;
        const value = target.type === 'checkbox' ? target.checked : target.value;
        const name = target.name;
        this.setState({
            [name]: value
        });
    }


    handleSubmit(event) {
        event.preventDefault();
        try {
            Reservation.insert(this.state, function(error) { error ? console.log( 'Insert Error', error) : null});
        } catch (e) {
            console.error(e);
            M.toast({
               html: e.reason,
            });
        }
    }

    render() {
        const $ = this;
        return (
            <div className="row">
                <h5>Reservierung anlegen</h5>
                <form className="col s6" onSubmit={this.handleSubmit}>
                    <div className="row">
                        <label htmlFor='parkingLot'>Parkplatz</label>
                        <MaterialSelect ided='parkingLot'
                                        named='parkingLot'
                                        labeled='Parkplatz'
                                        textField='name'
                                        valueField='_id'
                                        options={this.props.lots}
                                        placeholder='Parkplatz wählen'
                                        onChange={this.handleInputChange}/>
                    </div>
                    <div className="row input-field">
                        <input id='begin' name='begin' type='text' className='datepicker'
                               data-value={this.state.begin}/>
                        <label className='' htmlFor='begin'>Anfang</label>
                    </div>
                    <div className="row input-field">
                        <input id='end' name='end' type='text' className='datepicker'
                               data-value={this.state.end}/>
                        <label className='' htmlFor='end'>Ende</label>
                    </div>
                    <button className="btn waves-effect waves-light" type="submit" name="action"><i
                        className="material-icons right">create</i>Anlegen
                    </button>
                </form>
            </div>
        );
    }
}

export default withTracker(() => {
    Meteor.subscribe('parkingLots');
    return {
        lots: ParkingLot.find({}).fetch(),
    };
})(ReservationForm);

MaterialSelect.js

import React, {Component} from "react";
import {Random} from "meteor/random";
import * as M from "materialize-css";

export default class MaterialSelect extends Component {

    constructor(props) {
        super(props);
        this.state = {value: this.props.value};
    }

    componentDidMount() {
        let select = document.querySelector(`#${this.props.ided}`);

        //M.FormSelect.init(select, {});
    }

    handleInputChange(event, $) {
        event.preventDefault();
        $.props.onChange(event);
        const target = event.target;
        const value = target.type === 'checkbox' ? target.checked : target.value;
        const name = target.name;

        this.setState({
            [name]: value
        });
    }

    render() {
        const options = this.props.options.map(option => {
            return <option value={!!this.props.valueField ? option[this.props.valueField] : option}
                           key={Random.id(4)}>{!!this.props.textField ? option[this.props.textField] : option}</option>
        });

        const $ = this;
        return (
                <select id={this.props.ided}
                        name={this.props.named}
                        defaultValue=''
                        value={this.state.value}
                        className='no-autoinit browser-default'
                        onChange={function(event) {$.handleInputChange(event, $)}} >
                    <option value="" disabled>{this.props.placeholder}</option>
                    <option value="crap value">Not Existing Value Test</option>
                    {options}
                </select>
        );
    }


}

2 个答案:

答案 0 :(得分:0)

我尝试过:

 <script>
  const res = {
    date: new Date(),
    parkingLot: {
      _id: 11,
      number: 12,
      name: 'jhon',
      description: 'j',
      price: 3232,
      reserved: true,
    },
    user: 'j',
    begin: 'j',
    end: 'j',
  };

console.log(res);
</script>

,并且效果很好。 您确定所有属性实际上都在那里吗?尝试在控制台中对其进行调试。 “ this.state.parkingLot._id”实际上返回数字吗?

答案 1 :(得分:0)

您是否在组件构造函数中绑定了this

class MyComponent extends React.Component {
  constructor(props) {
    super(props)

    this.handleSubmit = this.handleSubmit.bind(this)
  }

  handleSubmit(evt) {
   ...
  }
}

或者,您可以使用类属性,然后将事件处理程序声明为箭头函数。为此,您将需要babel插件@babel/plugin-proposal-class-properties

也请看一下:https://reactjs.org/docs/faq-functions.html