2017-12-08 11 views
-1

Ich drucke die Daten aus einer API in eine Tabelle, und ich habe Schwierigkeiten, die Spaltenwerte alphabetisch und numerisch zu sortieren. Wenn die Spalten Daten innerhalb der API von numerischen Werten besteht, dh 10.01, 333.01, 8.99 or 100.88 usw. sortieren sie aus 0 -> 100 auf den ersten Klick und auf dem zweiten Klick absteigend 100 -> 0 und in der gleichen Logik für alphabetisch Werte, dh a-z && Z-A und umgekehrt.ReactJS: onClick() Sortierung für dynamisch gerenderte <th> Elemente

Die Funktion, die ich kenne onclick="sortTable(0)" funktioniert nicht in der gleichen Weise in React, wie ich es in javaScript zu codieren. Wahrscheinlich irre ich den ES6-Standard, aber ich bin mir nicht sicher.

Here is how it's look like my table without sorting functionality.

Hier ist mein Codebeispiel mit onclick="sortTable(0)", aber es ist nicht gut funktioniert:

class App extends React.Component 
{ 
    constructor() 
    { 
     super(); 
     this.state = { 
      rows: [], 
      columns: [], 
      clicked: false 
     } 

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

    handleClick() 
    { 
     this.setState({ 
      clicked: true 
     }); 
    } 


    sortTable(n) 
{ 
      var table, columns, switching, i, x, y, shouldSwitch, dir, switchcount = 0; 
      table = document.getElementById("datagrid"); 
      switching = true; 
      //Set the sorting direction to ascending: 
      dir = "asc"; 
      /*Make a loop that will continue until 
      no switching has been done:*/ 
      while (switching) 
      { 
       //start by saying: no switching is done: 
       switching = false; 
       columns = table.getElementsByTagName("TH"); 
       /*Loop through all table rows (except the 
       first, which contains table headers):*/ 
       for (i = 1; i < (columns.length - 1); i++) 
       { 
        //start by saying there should be no switching: 
        shouldSwitch = false; 
        /*Get the two elements you want to compare, 
        one from current row and one from the next:*/ 
        x = columns[i].getElementsByTagName("TH")[n]; 
        y = columns[i + 1].getElementsByTagName("TH")[n]; 
        /*check if the two rows should switch place, 
        based on the direction, asc or desc:*/ 
        if (dir == "asc") 
        { 
         if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) 
         { 
          //if so, mark as a switch and break the loop: 
          shouldSwitch = true; 
          break; 
         } 
        } else if (dir == "desc") 
        { 
         if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) 
         { 
          //if so, mark as a switch and break the loop: 
          shouldSwitch = true; 
          break; 
         } 
        } 
       } 
       if (shouldSwitch) 
       { 
        /*If a switch has been marked, make the switch 
        and mark that a switch has been done:*/ 
        rows[i].parentNode.insertBefore(rows[i + 1], rows[i]); 
        switching = true; 
        //Each time a switch is done, increase this count by 1: 
        switchcount++; 
       } else 
       { 
        /*If no switching has been done AND the direction is "asc", 
        set the direction to "desc" and run the while loop again.*/ 
        if (switchcount == 0 && dir == "asc") 
        { 
         dir = "desc"; 
         switching = true; 
        } 
       } 
      } 
     } 

    componentDidMount() 
    { 

     fetch("http://ickata.net/sag/api/staff/bonuses/") 
      .then(function (response) 
      { 
       return response.json(); 
      }) 
      .then(data => 
      { 
       this.setState({ rows: data.rows, columns: data.columns }); 
      }); 

    } 

    render() 
    { 

     return (
      <div id="container" className="container"> 
       <h1>Final Table with React JS</h1> 
       <table className="datagrid"> 
        <thead> 
         <tr> { 
          this.state.columns.map((column, index) => 
          { 
           return (<th onClick={this.handleClick}>{column}</th>) 
          } 
          ) 
         } 
         </tr> 
        </thead> 
        <tbody> { 
         this.state.rows.map(row => (
          <tr>{row.map(cell => (
           <td>{typeof cell === 'number' ? cell.toFixed(2) : cell}</td> 
          ))} 
          </tr> 
         )) 
        } 
        </tbody> 
       </table> 
      </div> 
     ) 
    } 
} 


ReactDOM.render(<div id="container"><App /></div>, document.querySelector('body')); 

Sie sind willkommen, direkt zu meinem Repo beitragen: Fetching API data into a table

Meine Beispiel, direkt nach der onclick="sortTable(0)" wurde verwendet, keine Fehler in der co Nsole, aber es druckt das gleiche Ergebnis. Ich denke, ich handle nicht korrekt die <th onClick={this.handleClick}>{column}</th> Elemente.

onClick event doesn't dunction

Leider war ich nicht finden können bezogene Dokumentation bei ReactJs.org

funktioniert Es ist überhaupt nicht das OnClick-Ereignis, so dass ich auch nicht die sor Funktionalität debuggen können.

Irgendwelche Vorschläge werden geschätzt!

Antwort

0

onClick =() => this.sortable (0). Wenn Sie in diesem Fall irgendeine Art von Schleife verwenden, müssen Sie den Index an eine andere Funktion übergeben, um den korrekten Indexwert zu durchlaufen. sehen Sie diesen Link, um Erläuterungen zu React OnClick for item not working

+0

Hallo @ stack26 danke für die Antwort, aber ich denke nicht, dass dies für meinen Fall relevant ist. Zuerst haben wir hier separate Arrays: Spalten und Zeilen, die obige Beschreibung Ich sage, dass ich die Sortierfunktion der Zeilenwerte durch onClick-Ereignis durch die Spaltenkopfelemente behandeln möchte. – antdimit

0

Ich sehe nicht, wo der Code tatsächlich ruft die sortTable Methode, aber ich glaube, es ist ein größeres Problem hier.

Sie sollten DOM Manipulation nicht manuell tun, es sei denn, Sie haben einen sehr guten Grund. Verlassen Sie sich stattdessen auf Reagieren, um das DOM zu manipulieren, weshalb Sie es verwenden. Sie sind dafür verantwortlich, die Anzeige einer Komponente basierend auf ihrer internen state und ihrer props zu beschreiben, was die render() Funktion widerspiegeln sollte. In Ihrem Fall hängt die Reihenfolge der Zeilen von der aktuellen Sortierspalte und der Sortierrichtung ab. So könnten Sie einen zusätzlichen Status für sort hinzufügen, der ein Objekt sein könnte, das die column zum Sortieren und direction der Sorte enthält. Wenn auf eine Spalte geklickt wird, aktualisieren Sie sort, wodurch Ihre Komponente erneut gerendert wird. Dann würde Ihre render()-Funktion den aktuellen sort-Status berücksichtigen, wenn die Zeilen angezeigt werden.

also die Zeilen zu machen, könnte man schreiben:

renderRows() { 
    const sortFn = getSortFunction(this.state.sort); // defined elsewhere 

    // shallow copy so we don't mutate the state 
    return [ ...this.state.rows ] 
    .sort(sortFn) 
    .map((row, i) => (
     <tr key={i}> 
     { row.map((cell, j) => <td key={j}>{ cell }</td>) } 
     </tr> 
    )); 
} 

render() { 
    return (
    <table> 
     <thead>{ renderHeader() }</thead> 
     <tbody>{ renderRows() }</tbody> 
    </table> 
); 
} 

Auch wenn eine App Reagieren Rendering, die ReactDOM.render() Aufruf ersetzt den Inhalt des DOM-Element mit dem Element Reagieren Sie. Es ist üblich, dass Sie als App-Container einen <div id="root"> verwenden und dann den Inhalt durch Ihre App ersetzen.

ReactDOM.render(<App />, document.getElementById("root")); 
+0

Danke für die Rückmeldung, aber Ihr Vorschlag funktioniert nicht, weil Sie nirgends ** 'renderHeader' ** definieren. Das Rendering funktioniert nicht mit Ihrer Anweisung, da ich den Body zwischen den '' Elementen darstellen muss, ansonsten einfach nichts ausdrucken, und anstelle von' root' ist meine 'id'' container'. 'ReactDOM.render (

, document.querySelector ('body'));' – antdimit

+0

Es sollte nicht kopiert und eingefügt werden. Wenn Sie nicht verstehen, wie die Funktionen "getSortFunction" und "renderHeader" implementiert werden sollen, kann ich Ihnen helfen, wenn Sie sich etwas Mühe geben. Außerdem können Sie die jsx in 'render()' ändern, um Ihre Bedürfnisse zu reflektieren, ich habe nur ein Beispiel gegeben. –

Verwandte Themen