我还在学习React和Javascript,感谢您的耐心等待。
我正在尝试序列化我的表单数据,以便将其发送到Ruby on Rails后端进行处理。我只是使用vanilla React而没有其他依赖,如Flux,Redux等。
好像我的孩子组件没有返回任何东西,我不太清楚为什么。
我试过了:
我的JSFiddle:https://jsfiddle.net/morahood/0ptdpfu7/91/
我显然错过了React设计模式的关键元素。我离开轨道了吗?我怎样才能回到正轨?我希望最终能够以下列格式序列化表单数据
{
"service_request" : {
"services" : [
{
"service_item" : ["Oil Change", "New Windshield Wipers"],
"customer" : "Troy",
"manufacturer" : "Ford",
"model" : "F150"
},
{
"service_item" : ["Tire Rotation"],
"customer" : "Dave",
"manufacturer" : "Hyundai",
"model" : "Genesis"
}
]
}
}
var ServiceForm = React.createClass({
render: function() {
return (
<form onSubmit={ this.handleFormSubmission }>
{ this.state.serviceItems.map(function(item) {
return (item);
})}
<div className="btn btn-default btn-sm" onClick={ this.addServiceItem }>+ Append New Service Item</div>
<button type="submit" className="btn btn-success btn-lg pull-right">Submit</button>
</form>
);
},
getInitialState: function() {
return ({
serviceItems: [<ServiceItem serializeServiceItem={ this.serializeServiceItem } />]
});
},
handleFormSubmission: function() {
console.log("form submitted!");
alert("Serialized Form Data: " + this.serializeFormData());
},
addServiceItem: function(event) {
var serviceItems = this.state.serviceItems;
serviceItems.push(<ServiceItem serializeServiceItem={ this.serializeServiceItem } />);
this.setState({
serviceItems: serviceItems
});
},
serializeServiceItem: function() {
var jsonData = {
"service_item" : this.state.service_items,
"customer" : this.state.customer,
"manufacturer" : this.state.manufacturer,
"model" : this.state.model
}
return (jsonData);
},
serializeFormData: function() {
return( this.state.serviceItems.map(function(item) {
return (item.serializeServiceItem);
}));
}
});
var ServiceItem = React.createClass({
render: function() {
return (
<div className="row">
<div className="col-sm-3">
<div className="form-group">
<label>Service Item </label>
<select multiple name="service_item" selected={ this.state.service_items } className="form-control">
<option>Oil Change</option>
<option>Tire Rotation</option>
<option>New Wiper Blades</option>
</select>
</div>
</div>
<div className="col-sm-3">
<div className="form-group">
<label>Customer </label>
<select name="customer" selected={ this.state.customer } className="form-control">
<option>Troy</option>
<option>Dave</option>
<option>Brandon</option>
</select>
</div>
</div>
<div className="col-sm-3">
<div className="form-group">
<label>Manufacturer </label>
<div className="input-group">
<input name="manufacturer" value={ this.state.manufacturer } onChange={ this.setManufacturer } type="text" className="form-control" />
</div>
</div>
</div>
<div className="col-sm-3">
<div className="form-group">
<label>Model </label>
<div className="input-group">
<input name="model" value={ this.state.model } onChange={ this.setModel } type="text" className="form-control" />
</div>
</div>
</div>
</div>
);
},
getInitialState: function() {
return({
service_items: [],
customer: "",
manufacturer: "",
model: ""
});
},
setModel: function(event) {
this.setState({ model: event.target.value });
},
setManufacturer: function(event) {
this.setState({ manufacturer: event.target.value });
},
setCustomer: function(event) {
this.setState({ customer: event.target.selected });
},
setServiceItems: function(event) {
this.setState({ service_items: event.target.selected });
}
});
ReactDOM.render(
<ServiceForm />,
document.getElementById('container')
);
答案 0 :(得分:1)
你&#34;可能&#34;在这里过分复杂的事情。 irb(main):001:0> Property.find(1)
Property Load (2.2ms) SELECT "properties".* FROM "properties" WHERE "properties"."id" = $1 LIMIT 1 [["id", 1]]
Property Load (2.2ms) SELECT "properties".* FROM "properties" WHERE "properties"."id" = $1 LIMIT 1 [["id", 1]]
=> #<Property id: 1, listing_status: "In Draft", my_property_reference: "My reference", floor_area: 350, land_area: 500, state: "New Development", city: "Sydney", area: "CBD", street: "123 fake st", price: 800000, floors: 2, property_type: "Apartment", property_age: nil, completion: 2016, bedrooms: 5, bathrooms: 2, under_cover_car_spaces: 3, car_spaces: nil, car_lock_up_garage: 1, additional_information: "Great location in a great area.", description: "great house great house great house great house gr...", created_at: "2016-02-04 03:44:54", updated_at: "2016-02-04 03:46:55", suburb: nil>
irb(main):002:0> Image.all
Image Load (1.8ms) SELECT "images".* FROM "images"
Image Load (1.8ms) SELECT "images".* FROM "images"
=> #<ActiveRecord::Relation []>
irb(main):003:0> Image
=> Image(id: integer, main: boolean, attachment: string, created_at: datetime, updated_at: datetime, property_id: integer)
irb(main):004:0>
的DOM元素实际上可以视为所有内部<form>
元素的数组。换句话说,如果你有:
<input>
您可以通过以下方式访问所有输入元素:
render: function() {
return (
<form ref="form">
...
</form>
);
}
这可能无法为您提供足够的灵活性。更好的解决方案可能是在组件实例中定义返回输入值的方法:
serialized = {}
for (var i in this.refs.form) {
var input = this.refs.form[i];
serialized[input.name] = input.value;
}
如果您需要多个服务项,那么您可能需要依靠var ServiceForm = React.createClass({
serializeFormData: function() {
return {
foo: this.refs.foo.serialize()
};
},
render: function() {
var foo = this.state.foo;
return (
<ServiceItem data={foo} ref="foo" />
);
}
});
var ServiceItem = React.createClass({
serialize: function() {
return {
model: this.refs.model.value,
...
}
},
render: function() {
var model = this.props.data.model;
return (
<input ref="model" value={model} ... />
);
}
});
来访问每个组件实例而不是this.props.children
:
this.refs
请注意,我在这里使用React.Children
而不是简单地使用var ServiceContainer = React.createClass({
collectFormData: function() {
return this.refs.form.serialize();
},
renderServiceItem: function(item, i) {
return (
<ServiceItem data={item} key={i} />
);
},
render: function() {
// Assuming you've moved all your state logic into this ServiceContainer
var serviceItems = this.state.serviceItems;
return (
<ServiceForm ref="form">
{serviceItems.map(this.renderServiceItem)}
</ServiceForm>
);
}
});
var ServiceForm = React.createClass({
serialize: function() {
return React.Children.map(this.props.children, function(item) {
return item.serialize();
});
},
render: function() {
return (
<div>{this.props.children}</div>
);
}
});
var ServiceItem = React.createClass({
serialize: function() {
// You can still access your input elements through refs in here
...
},
render: function() {
...
}
});
,因为当只有一个孩子时,this.props.children
不是一个数组(请参阅: https://facebook.github.io/react/tips/children-props-type.html)。
答案 1 :(得分:0)
您可以使用react.rb和reactive-record,它将为您提供开箱即用的所有功能。 http://reactrb.org