2017-07-26 5 views
1

Ich habe ein Array von Objekten addon_categories mit einer Eigenschaft id und einem anderen Array: addons. Wenn der Benutzer die Kontrollkästchen ändert, sollte der Status entsprechend aktualisiert werden: Dazu gehört das Hinzufügen zu oder das Entfernen aus dem Array 'Addons' unter der ausgewählten Kategorie.Wie aktualisiere ich den Status, indem ich ein Array innerhalb eines bestimmten Objekts aus einem Array von Objekten aktualisiere?

this.state = { addon_categories: [] }; 

// example of filled state 
this.state = { addon_categories: [ 
    { id: 3, addons: [ 1 ] }, 
    { id: 2, addons: [ 1, 4, 11 ] }, 
    { id: 4, addons: [ 3, 4] } 
] }; 

Dies ist eher ein Problem von JavaScript mehr als React, außer dass die Daten schließlich als Bestandteil Zustand aktualisiert werden muss. Als Anfänger von JavaScript kann ich das Zustandsobjekt nicht mit Objektarrays aktualisieren, die einige Eigenschaften und Arrays enthalten. Was ist die richtige Logik, um das Array addons in dem folgenden Code zu aktualisieren (sowohl für das Löschen von als auch für das Drücken von) nur für die bestimmte Kategorie?

Hier ist die Logik:

  1. Wenn ID Kategorie nicht vorhanden ist, einfach ein neues Objekt mit dem Kategorie-ID und Addons Array mit Single-Addon-ID hinzuzufügen. [✓]

  2. Wenn die Kategorie-ID existiert,
    -> prüfen, ob die addon_id in dieser Kategorie existiert.
    -> Wenn addon_id in dieser Kategorie existiert, entferne die Addon-ID aus diesem addons-Array in diesem Objekt [?]
    -> Wenn addon_id nicht existiert, drücke diese Addon-ID zu diesem addons-Array in diesem Objekt [?]

Hier ist mein Code.

import React from 'react'; 
import { connect } from 'react-redux'; 
import store from '../../../../reducers/store'; 
import fetchFood from '../../../../actions/restaurant/food_get'; 

class AddonsModal extends React.Component 
{ 
    constructor(props) 
    { 
     super(props); 
     this.state = { addon_categories: [] }; 

     this.onAddonChange = this.onAddonChange.bind(this); 
    } 

    /* 
    * Handle click, toggle addon change 
    */ 
    onAddonChange(e) 
    { 
     const c = +e.target.name; // category_id from input 
     const a = +e.target.id; // addon_id from input 

     // create new instance of this.state.addon_categories 
     let addon_categories = this.state.addon_categories.slice(); 

     if (!this.addonCategoryExists(c)) 
     { 
      // CATEGORY DOESNT EXIST, SO NEW CATEGORY AND ADDON ADDED! 
      addon_categories.push({ id: c, addons: [a] }); 
      this.setState({ addon_categories },() => console.log('NEW STATE', this.state.addon_categories)); 
     } 
     else 
     { 
      // CATEGORY EXISTS 
      if (this.addonExistsInCategory(c, a)) 
      { 
       // ?? ADDON EXISTS IN THIS CATEGORY, SO NEED TO REMOVE IT 
      } 
      else 
      { 
       // ?? ADDON DOESNT EXIST IN CATEGORY SO NEED TO ADD IT TO JUST THIS CATEGORY 
      } 
     } 

    } 

    addonCategoryExists(c) 
    { 
     return !! this.state.addon_categories.filter(category => category.id === c).length; 
    } 

    addonExistsInCategory(c, a) 
    { 
     let verified = false; 
     let categories = this.state.addon_categories.filter(category => category.id === c); 
     categories.forEach(category => 
     { 
      if (category.addons.includes(a)) { verified = true; } 
     }); 
     return verified; 
    } 

    componentDidMount() 
    { 
     store.dispatch(fetchFood(this.props.Restaurant.id, this.props.food.id)); 
    } 

    render() 
    { 
     let food = this.props.food; 
     let foodData = this.props.foodDetails.food.data; 
     let addon_categories = foodData ? foodData.data.addon_category : null; 

     return (


          <div className="row"> 

           {addon_categories && addon_categories.map(category => { return (

            <div className="col-xs-12" key={category.id}> 
             <div className="pop-up-dish-specials"> 
              <h2>{category.name}</h2> 

              {category.addons && category.addons.map(addon => { return (

               <div key={addon.id}> 
                {/* for simplicity, i've sent the category_id in name and addon_id in id property */} 
                <input type="checkbox" name={category.id} id={addon.id} onChange={this.onAddonChange}/> 
                <label htmlFor={addon.id}>{addon.name}</label> 
               </div> 

              )})} 

             </div> 
            </div> 

           )})} 

          </div> 


     ) 
    } 
} 

function mapStateToProps(state) 
{ 
    return { foodDetails: state.foodDetails } 
} 

export default connect(mapStateToProps)(AddonsModal); 

Antwort

1

Ich möchte nur einfach .map und .filter verwenden, wenn Add-on besteht daher für die Entfernung:

const newCategories = this.state.addon_categories.map(category => { 
    if (category.id === c) { 
     const newAddons = category.addons.filter(addon => addon !== a); 
     return { id: category.id, addons: newAddons }; 
    } else { 
     return category; 
    }   
}); 
this.setState({ addon_categories: newCategories }); 

es für das Hinzufügen so sein würde:

const newCategories = this.state.addon_categories.map(category => { 
    if (category.id === c) { 
     const newAddons = category.addons.concat([a]) 
     return { id: category.id, addons: newAddons }; 
    } else { 
     return category; 
    }   
}); 
this.setState({ addon_categories: newCategories }); 

Es gibt jedoch wahrscheinlich eine bessere Lösung für dieses Problem.

+0

Das ist eine gute Lösung, vielen Dank. – anonym

+0

Ich möchte die Löschbedingung in zwei weiter aufgliedern. '[# 1]' entferne das gesamte 'addon_category Objekt', wenn das das einzige Addon ist und' [# 2.] 'Entferne einfach das Addon aus dem Array wenn es mehrere gibt (✓ ✓). Ich kann # 1 nicht mit 'if (category.id === c && category.addons.length === 1) {return addon_categories.splice (index, 1); } ' – anonym

+0

Ihre Lösung wird nicht funktionieren, weil Splice gelöschte Objekte zurückgibt, daher hilft es Ihnen nicht. Sie können 2 Dinge tun - entweder ändern Sie einfach meinen Code zurück zu so etwas wie 'newAddons.length? {id: category.id, addons: newAddons}: undefined 'und dann, wenn du den Status setzt, wirst du' addon_categories: newCategories.filter (category => category) 'machen (auf diese Weise filterst du einen undefinierten Wert aus deinem Array) Um dies zu tun, speichern Sie den Wert des Index der Kategorie und verwenden Sie dann den Spleiß, um ihn vor der Statuseinstellung aus newCategories zu löschen. –

1
if (this.addonExistsInCategory(c, a)) { 
     // ADDON EXISTS IN THIS CATEGORY, SO NEED TO REMOVE IT 
     addon_categories.find(function(obj) { 
     if (obj.id == c) { 
      obj.addons.splice(obj.addons.indexOf(a), 1); 
     } 
     }); 
    } else { 
     // ADDON DOESNT EXIST IN CATEGORY SO NEED TO ADD IT TO JUST THIS CATEGORY 
     addon_categories.find(function(obj) { 
     if (obj.id == c) { 
      obj.addons.push(a); 
     } 
     }); 
    } 
this.setState({ addon_categories },() => console.log('NEW STATE', this.state.addon_categories)); 
+0

@Oliver Wenn dies Ihre Anfrage löst, können Sie dies als Antwort markieren –

+0

Dies löst das Problem, als Sie sehr. – anonym

Verwandte Themen