2016-03-24 2 views
3

Я создаю <table> с React 0.14.6, который имеет ряд заголовков столбцов, которые динамически вставленный в <thead> из <table>:Как динамически вставлять данные ячейки таблицы html в таблицу с динамическими заголовками в React?

CourseTable.js:

import CourseList from './CourseList'; 
import GradesHeader from './GradesHeader'; 
import React, {Component} from 'react'; 

export default class CourseTable extends Component { 
    /** 
    * Gets all unique terms that have grades 
    * @param courses {Array} 
    * @return {Array} 
    */ 
    getUniqueTerms(courses) { 
    let uniqueTerms = []; 
    courses.forEach(course => { 
     if (course.grades) { 
     Object.keys(course.grades).forEach(term => { 
      if (uniqueTerms.indexOf(term) === -1) { 
      uniqueTerms.push(term); 
      } 
     }) 
     } 
    }); 
    return uniqueTerms; 
    } 

    createGradesHeaders(courses) { 
    return this.getUniqueTerms(courses).map(term => { 
     return (
     <th> 
      <GradesHeader headerText={term}/> 
     </th> 
    ); 
    }); 
    } 

    render() { 
    let headers = this.createGradesHeaders(this.props.courses); 
    return (
     <table className="table table-bordered table-condensed"> 
     <thead> 
     <tr> 
      <th> 
      Period 
      </th> 
      <th> 
      Class 
      </th> 
      <th> 
      Term 
      </th> 
      <th> 
      Date Enrolled 
      </th> 
      <th> 
      Date Left 
      </th> 
      <th> 
      <div>Absenses</div> 
      <div>All (Excused)</div> 
      </th> 
      <th> 
      Tardies 
      </th> 
      <th></th> 
      {headers} 
      <th> 
      Teacher 
      </th> 
     </tr> 
     </thead> 
     <CourseList courseData={this.props.courses}/> 
     </table> 
    ); 
    } 
} 

GradesHeader.js:

import React, {Component} from 'react'; 

export default class GradesHeader extends Component { 
    render() { 
    return (
     <div> 
     {this.props.headerText} 
     </div> 
    ); 
    } 
} 

Course.js:

import React, {Component} from 'react'; 

export default class Course extends Component { 
    render() { 
    const unexcused = !!this.props.courseData.attendance.unexcused ? this.props.courseData.attendance.unexcused : 0; 
    const excused = !!this.props.courseData.attendance.excused ? this.props.courseData.attendance.excused : 0; 
    const totalAbsences = unexcused + excused; 
    return (
     <tr> 
     <td> 
      {this.props.courseData.expression} 
     </td> 
     <td> 
      {this.props.courseData.course_name} 
     </td> 
     <td> 
      {this.props.courseData.abbreviation} 
     </td> 
     <td> 
      {this.props.courseData.dateenrolled} 
     </td> 
     <td> 
      {this.props.courseData.dateleft} 
     </td> 
     <td> 
      {totalAbsences} 
      ({excused}) 
     </td> 
      // Grades for this course go here 
     <td> 
     </td> 
     <td> 
      {this.props.courseData.lastfirst} 
     </td> 
     </tr> 
    ); 
    } 
} 

Вы можете увидеть в CourseTable.js, где я динамически генерирую заголовки для этого раздела таблицы <thead>. Я смущен тем, как вставлять/вырезать данные для каждого класса в соответствующий столбец.

Я думаю, мне нужно как-то идентифицировать каждый из элементов заголовка <th>, которые динамически сгенерированы, и ссылаться на них при вставке в эти столбцы, но я не уверен, как это сделать.

+0

Так как React повторно отображает после изменения состояния, то, что вам нужно сделать, это добавить новую строку в состояние, а затем передать ее компоненту для визуализации в виртуальную DOM. Затем виртуальная DOM выяснит, что изменилось и внесла изменения в реальную DOM. – Derek

+0

Не могли бы вы привести пример того, что вы предлагаете? У меня возникли проблемы с выходом из рабочего решения исключительно из вашего комментария. –

ответ

1

Вы должны, как упоминалось в комментарии, использовать состояния. Государства очень полезны. ReactJS states Если вы хотите создавать новые заголовки pidgeonhole, вы можете назначить их идентификатором, чтобы вы могли правильно их прокручивать при рендеринге нового. Как уже упоминалось, реагировать на изменение состояния. Есть несколько примеров этого на странице руководства по facebook, а также в документации.

Скажите, что вы собрали все свои заголовки в объекте или, возможно, из базы данных.

var headers = [{id: 0, name: grade} 
       {id: 1, name: term} 
] 

Так что в вашем методе визуализации головок вы можете поместить их в так:

constructor(props) { 
    super(props); 
    this.state = { 
     headers: headers, 
    } 
}, 

sortAlg(arr) { 
    //Choose one, make one 
}, 

render() { 
this.sortAlg(this.state.headers); 
var headerArr = []; 
headers.forEach(function(header) { 
    headerArr.push(<YourHeader header = {header} /> 
}); 
return (
    <table className="table table-bordered table-condensed"> 
    <thead> 
     {headerArr} 
    </thead> 
    <CourseList courseData={this.props.courses}/> 
    </table> 
); 

<YourHeader /> является компонентом, который делает для лучшего контроля. Как мне нравится делать это, по крайней мере.

Надеюсь, это поможет, удачи.

1

Если я хорошо понимаю вопрос и структуру данных, вы можете передать оценки, рассчитанные с помощью getUniqueTerms, на ваш CourseList компонент.

Так в CourseTable.js:

render() { 
    let grades = this.uniqueTerms(this.props.courses); 
    let headers = this.createGradesHeaders(grades); 
    // and then in your jsx 
    <CourseList courseData={ this.props.courses } grades={ grades } /> 
} 

И в render методы Вашего Course компонента:

{ 
    this.props.grades.map(grade => 
     <td key={ grade }> 
      // whatever data you need to print from this.props.courseData.grades[grade] 
     </td> 
    ) 
} 

Надеется, что это помогает!

Смежные вопросы