Ich habe eine Arbeits App mit Ruby on Rails und ReactJS die vier Komponenten:aktualisieren zwei Komponenten keine Beziehung Ruby on Rails & ReactJS
- ProductContainer
- ProductItem (Kind von ProductContainer)
- BasketContainer
- BasketItem (Kind BasketContainer)
im Moment ist Ajax neuer Warenkorb Artikel erstellen verwenden ruft wh de Klicken Sie in der Produktartikel-Komponente auf die Schaltfläche "In den Warenkorb". Das funktioniert einwandfrei, aber der Status wird nicht aktualisiert, ohne dass die Seite aktualisiert wurde. Ich bin mir nicht sicher, wie ich BasketContainer/BasketItem darauf hinweisen soll, dass die Komponente erneut gerendert werden muss.
Ich glaube, ich muss SetState auf den Erfolg meiner Ajax-Anruf, aber bin mir nicht sicher, wie dies für eine andere Komponente zu tun. Jeder Rat würde sehr geschätzt werden.
ProductItem Component
class ProductItem extends React.Component{
constructor() {
super()
this.state = {
name: '',
price: 0,
code: '',
id: ''
}
}
componentWillMount() {
this.setState({
name: this.props.data.name,
price: this.props.data.price,
code: this.props.data.code,
id: this.props.data.id
})
}
addtoBasket() {
$.ajax({
type: "POST",
url: "/items",
dataType: "json",
data: {
item: {
name: this.state.name,
price: this.state.price,
code: this.state.code
}
},
success: function() {
console.log("success");
},
error: function() {
console.log("error");
}
})
}
render(){
let productName = this.props.data.name
let productPrice = this.props.data.price
let productCode = this.props.data.code
let productImg = this.props.data.image_url
return (
<div className="col-xs-12 col-sm-4 product">
<img src={productImg}/>
<h3 className="text-center">{productName}</h3>
<h5 className="text-center">£{productPrice}</h5>
<div className="text-center">
<button onClick={this.addtoBasket.bind(this)} className="btn btn-primary">Add to Basket</button>
</div>
</div>
)
}
}
BasketItem Component
class BasketItem extends React.Component{
constructor(props) {
super()
this.state = {
name: '',
price: 0,
code: '',
id: '',
quantity: 1,
}
}
componentWillMount() {
this.setState({
name: this.props.data.name,
price: this.props.data.price,
code: this.props.data.code,
id: this.props.data.id,
})
}
deleteItem() {
let finalUrl = '/items/' + this.state.id;
$.ajax({
type: "DELETE",
url: finalUrl,
dataType: "json",
success: function(response) {
console.log("successfully deleted");
},
error: function() {
console.log("error");
}
})
}
render(){
let itemName = this.props.data.name
let itemCode = this.props.data.code
let itemQuantity = 1
let itemPrice = (this.props.data.price * itemQuantity).toFixed(2)
const itemId = this.props.data.id
return(
<tr>
<td>{itemName}</td>
<td>{itemCode}</td>
<td>{itemQuantity}</td>
<td><button className="btn btn-warning" onClick={this.deleteItem.bind(this)}>Remove</button></td>
<td>£{itemPrice}</td>
</tr>
)
}
}
Pr oductContainer Komponente
class ProductContainer extends React.Component {
constructor() {
super()
this.state = {
products: []
}
}
componentWillMount() {
this.setState({
products: this.props.products
})
}
render(){
let p = this.state.products
return(
<div>
<h1>Products</h1>
<div className="row">
{p.map(function(product){
return <ProductItem data={product} key={product.id} />;
})}
</div>
</div>
)
}
}
BasketContainer Komponente
class BasketContainer extends React.Component{
constructor() {
super()
this.state = {
items: [],
subTotal: 0,
totalPrice: 0,
deliveryPrice: 0
}
}
componentWillMount() {
this.setState({
items: this.props.items,
})
}
componentDidMount() {
this.calculateTotals();
}
calculateTotals() {
let subtotal = this.state.subTotal
let delivery = this.state.deliveryPrice
for (var i=0; i<this.state.items.length; i++) {
subtotal += Number(this.state.items[i].price);
}
if (subtotal > 90) {
delivery = 0;
} else if (subtotal >= 50 & subtotal < 90) {
delivery = 2.95;
} else {
delivery = 4.95;
}
this.setState({
deliveryPrice: delivery,
subTotal: subtotal,
totalPrice: subtotal + delivery
})
}
render(){
const {
totalPrice,
subTotal,
deliveryPrice
} = this.state;
let i = this.state.items
let basketBlock;
let basketCount;
let basketSubtotal;
let basketDelivery;
let basketTotal;
if (i) {
if (i.length === 1) {
basketCount = (
<span className="basket-count">
({i.length} item)
</span>
)
} else {
basketCount = (
<span className="basket-count">
({i.length} items)
</span>
)
}
basketSubtotal = (
<tr>
<td></td>
<td></td>
<td></td>
<th>Subtotal</th>
<td>£{subTotal.toFixed(2)}</td>
</tr>
)
basketDelivery = (
<tr>
<td></td>
<td></td>
<td></td>
<th>Delivery</th>
<td>£{deliveryPrice.toFixed(2)}</td>
</tr>
)
basketTotal = (
<tr>
<td></td>
<td></td>
<td></td>
<th>Total</th>
<td>£{totalPrice.toFixed(2)}</td>
</tr>
)
basketBlock = (
<div className="col-xs-12">
<div className="well">
<table className="table table-responsive">
<thead>
<tr>
<th>Product</th>
<th>Code</th>
<th>Quantity</th>
<th>Actions</th>
<th>Price</th>
</tr>
</thead>
<tbody>
{i.map(function(item){
return <BasketItem data={item} key={item.id} />;
})}
{basketSubtotal}
{basketDelivery}
{basketTotal}
</tbody>
</table>
</div>
</div>
)
} else {
basketCount = (
<span className="basket-count">
pluralize(0 Items)
</span>
)
basketBlock = (
<div className="col-xs-12">
<div className="well">
<h5>Add an item</h5>
</div>
</div>
)
}
return(
<div>
<h1>Basket {basketCount}</h1>
<div className="row">
{basketBlock}
</div>
</div>
)
}
}
Seiten Index - wo die Komponenten in die Ansicht montiert sind
<div class="container-fluid">
<div class="row">
<div class="col-xs-12 col-sm-8">
<%= react_component('ProductContainer', render(template: 'products/index.json.jbuilder')) %>
</div>
<div class="col-xs-12 col-sm-4 basket">
<%= react_component 'BasketContainer', render(template: 'items/index.json.jbuilder') %>
</div>
</div>
Hey Amit, vielen Dank für Ihre Antwort lösen sollte. :) Auf welche Kinder- und Elternteile beziehst du dich? –
Die Komponente, die Sie aktualisieren möchten, ist die Komponente, die Sie untergeordnete haben. Also ist es einfach. In Ihrem Fall BasketContainer Component ist die Eltern und BasketItem ist Kind. :) – Amit
Ich glaube nicht, dass dies funktionieren wird, da die Schaltfläche Zum Warenkorb hinzufügen in der ProductItem-Komponente und dann die HandleCallback-Funktion in der BasketContainer-Komponente ist.In Schienen werden diese separat in die Ansicht eingefügt und es scheint keine Beziehung zwischen ihnen zu bestehen. Ich füge die Ansicht zu der Frage hinzu, damit du sehen kannst, was ich meine :) –