DynamicRequestorDetails
,获取要添加到其中的可能组件的列表(例如文本框或下拉列表)。这一个可以工作,并生成文本框/下拉列表。我的问题是
handleChange
父容器的事件似乎没有传递给组件处理程序生成的动态组件。我还有什么遗漏吗?我看到正确地传递了这些值,但是在调试期间
手摇
动态创建的组件未触发事件。
我有以下文件:
下拉组件:
import React, {PropTypes} from 'react';
const Dropwdown = ({identifier, value, selectChanged, options, label}) => {
return (
<div className="row eis-field-row">
<label className="col-xs-4 TheSansBold">{label}</label>
<select className="col-xs-6"
name={identifier}
id={identifier}
onChange={selectChanged}
value={value}
>
<option value="">--Please select one--</option>
{
options.map((option) => {
return <option key={option.Value} value={option.Value}>{option.Text}</option>;
})
}
</select>
</div>
);
};
Dropwdown.propTypes = {
identifier: PropTypes.string,
defaultOption: PropTypes.object,
value: PropTypes.string,
selectChanged: PropTypes.func,
options: PropTypes.arrayOf(PropTypes.object),
label: PropTypes.string
};
export default Dropwdown;
组件处理程序:
import React from 'react';
/* import components here */
import Textbox from '../components/common/forms/Textbox';
import Dropdown from '../components/common/forms/Dropdown';
/* import component types */
import * as types from '../constants/FieldTypes';
export function getFieldValue(fieldValues, identifier) {
let selectedItem = fieldValues.find(x => x.FieldID == identifier);
if(Object.keys(selectedItem).length > 0) {
return selectedItem.Value;
}
}
export function RenderComponent(field, handleChange, value) {
switch(field.Type) {
case types.TextComponent: {
return (
<Textbox
type="text"
label={field.Label}
id={field.Identifier}
name={field.Identifier}
value={value}
onChange={handleChange}
placeholder={field.Placeholder}
key={field.Identifier}
/>
);
}
case types.SelectComponent: {
return (
<Dropdown
name={field.Identifier}
label={field.Label}
id={field.Identifier}
onChange={handleChange}
value={value}
options={field.Options}
key={field.Identifier}
/>
);
}
default: {
return null;
}
}
}
dynamiccrequestordetails组件:
import React, {PropTypes} from 'react';
import * as ch from '../../utilites/componentHandler';
const DynamicRequestorDetails = ({userinfo, ccValue, handleChange, isVisible, customFields, fieldValues}) => {
let wrapperClass = " hidden";
if(!isVisible) {
wrapperClass = "";
} else {
wrapperClass = " hidden";
}
return (
<div>
<label className="label-headers TheSansBold">REQUESTOR DETAILS</label>
<div className="row eis-field-row">
<label className="TheSansBold col-xs-4">Name</label>
<label id="requestorName" className="col-xs-6 field-value">{userinfo.DisplayName}</label>
</div>
<div className="row eis-field-row">
<label className="col-xs-4 TheSansBold ">Employee No</label>
<label className="col-xs-6 field-value">{userinfo.LanId}</label>
</div>
<div className="row eis-field-row">
<label className="col-xs-4 TheSansBold">Department</label>
<label className="col-xs-6 field-value">{userinfo.Department}</label>
</div>
<div className="row eis-field-row">
<label className="col-xs-4 TheSansBold">Designation</label>
<label className="col-xs-6 field-value">{userinfo.Title}</label>
</div>
<div className="row eis-field-row">
<label className="col-xs-4 TheSansBold">Contact No</label>
<label className="col-xs-6 field-value">{userinfo.Mobile}</label>
</div>
<div id="reqDivsion" className={"row eis-field-row" + wrapperClass}>
<label className="col-xs-4 TheSansBold">Divsion</label>
<select className="col-xs-6" onChange={handleChange}>
<option value="1">--Select Division--</option>
<option value="2">Group 1</option>
<option value="3">Group 2</option>
<option value="4">Group 3</option>
<option value="5">Group 4</option>
<option value="6">Group 5</option>
<option value="7">Group 6</option>
</select>
</div>
<div className={"row eis-field-row" + wrapperClass}>
<label className="col-xs-4 TheSansBold">Cost Center: </label>
<input type="text" value={ccValue} onChange={handleChange} className="col-xs-6" />
</div>
{
customFields.map(customField => {
let fieldValue = ch.getFieldValue(fieldValues, customField.Identifier);
return ch.RenderComponent(customField, handleChange, fieldValue);
})
}
</div>
);
};
DynamicRequestorDetails.propTypes = {
userinfo: PropTypes.object.isRequired,
ccValue: PropTypes.string,
handleChange: PropTypes.func,
divChange: PropTypes.func,
isVisible: PropTypes.bool,
customFields: PropTypes.arrayOf(PropTypes.object),
fieldValues: PropTypes.arrayOf(PropTypes.object)
};
export default DynamicRequestorDetails;
父组件:
const steps = def.ProcessPages[0].Steps;
class NewSMILEPage extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
FieldValues: []
};
this.handleChange = this.handleChange.bind(this);
this.goBack = this.goBack.bind(this);
}
componentDidMount() {
this.populateFieldValues();
}
componentWillReceiveProps(newProps) {
if(newProps.smile.FieldValues != this.props.smile.FieldValues) {
this.setState({FieldValues: newProps.smile.FieldValues});
}
}
handleChange(e, identifier) {
}
populateFieldValues() {
//populates values for my state
}
updateFieldValues(fv) {
//updates values for my state
}
goBack() {
//do some action
}
render() {
if(this.state.FieldValues.length > 0) {
return (
<div className="container-fluid">
<div className="row">
<div className="col-xs-4">
<FormHeader formName={this.props.eforms.SelectedEForm.Title} />
</div>
<div className="col-xs-8">
<StepTracker steps={def.ProcessPages[0].Steps} />
</div>
</div>
{/*Step Name and Image*/}
<div className="row form-label-container">
<img src={HeaderImage} alt="Header Image" width="40" className="pull-left"/>
<p className="form-header pull-left TheSansBold">NEW REQUEST</p>
</div>
<div className="row">
<div className="col-xs-6 pull-left">
<DynamicRequestorDetails
userinfo={this.props.userinfo}
isVisible={this.props.isVisible}
ccValue=""
ccValueChange={this.handleChange}
divChange={this.divisionChange}
customFields={def.ProcessPages[0].Fields}
handleChange={this.handleChange}
fieldValues={this.state.FieldValues}
/>
</div>
</div>
<div className="row footer-button-container footer">
<div className="pull-left">
<button id="btnBack" type="button" className="btn btn-back" onClick={this.goBack} >CANCEL</button>
</div>
<div className="pull-right">
<button id="btnNext" type="button" className="btn btn-next margin-right-lg" onClick={this.goNext}>NEXT</button>
</div>
</div>
</div>
);
} else {
return (<h1>Loading</h1>);
}
}
}
function mapStateToProps(state, ownProps) {
return {
//state to props returned here
};
}
function mapDispatchToProps(dispatch) {
return {
//actions returned here
};
}
NewSMILEPage.propTypes = {
//prop checking done here
};
export default connect(mapStateToProps, mapDispatchToProps)(NewSMILEPage);