如何使用Firebase创建动态HTML表格?

时间:2017-05-05 02:32:39

标签: javascript html reactjs firebase firebase-realtime-database

我尝试创建一个HTML表格,可以在我的用户使用我的应用时使用firebase实时更新。我真的很难让这个工作起来,我真的不知道从哪里开始。

基本上,它需要做的就是创建一个新的表行并在用户与我的应用程序交互时实时更新其单元格。

有没有人知道任何可以指向正确方向的好教程?创建HTML表的代码示例也很棒!感谢。

更新: 好!感谢Isaiah Lee,我出去找了一些React的教程。我有90%,但有一个问题,我似乎无法弄明白......

我可以在用户使用我的应用时动态更新我的表格,但我无法让他们填写数据。我觉得我非常接近,但是我对React的经验不足让我回到了这里......

出于某种原因,这里的循环并没有用任何数据填充td&#39>

render() {
return (
  <div className="App">

    <h1>Talkeetna Numbers</h1>
    <table id="numbers">
      <tbody>
        <tr>
          <th>Driver</th>
          <th>Coach</th>
          <th>Time</th>
          <th>Total People</th>
          <th>AM Train</th>
          <th>PM Train</th>
          <th>MEX</th>
          <th>Employees</th>
          <th>Seats Left</th>

        </tr>

        {this.state.rows.map(row =>
        <tr>
          <td>{this.state.driver}</td>
          <td>{this.state.coach}</td>
          <td>{this.state.time}</td>
          <td>{this.state.totalPeople}</td>
          <td>{this.state.amTrain}</td>
          <td>{this.state.pmTrain}</td>
          <td>{this.state.THEMEX}</td>
          <td>{this.state.Employees}</td>
          <td>{this.state.seatsLeft}</td>
        </tr>)}

    </tbody>
  </table>



  </div>
);

}

继承我的组件功能

componentDidMount()
{
  const logsRef = firebase.database().ref('logs');

  logsRef.on('child_added', snap => {


  this.addRow(snap.getKey());
  //rows.push(snap.getKey());
  console.log("adding key: ", snap.getKey());


   });

   console.log("loading rows...");

   for(var rowKey = 0; rowKey < this.state.rows.length; rowKey++)
   {

      const root = firebase.database().ref().child('logs/' + rowKey);
      const driverRef = root.child('Driver');
      const coachRef = root.child('Coach');
      const timeRef = root.child('Time');
      const totalPeopleRef = root.child('Total People');
      const AMTrainRef = root.child('AM Train');
      const PMTrainRef = root.child('PM Train');
      const MEXRef = root.child('MEX');
      const EmployeesRef = root.child('Employees');
      const seatsLeftRef = root.child('Seats Left');

      //sync with DB in real time
      driverRef.on('value', snap => {
        this.setState({
          driver: snap.val()
          })
        });
       coachRef.on('value', snap => {
         this.setState({
         coach: snap.val()
       })
       });
       timeRef.on('value', snap => {
       this.setState({
       time: snap.val()
          })
       });

       totalPeopleRef.on('value', snap => {
       this.setState({
        totalPeople: snap.val()
         })
       });

       AMTrainRef.on('value', snap => {
       this.setState({
       amTrain: snap.val()
          })
       });

      PMTrainRef.on('value', snap => {
      this.setState({
      pmTrain: snap.val()
        })
      });
      MEXRef.on('value', snap => {
        this.setState({
       THEMEX: snap.val()
        })
       });
      EmployeesRef.on('value', snap => {
      this.setState({
      Employees: snap.val()
       })
       });
       seatsLeftRef.on('value', snap => {
          this.setState({
          seatsLeft: snap.val()
          })
      });

     }


    }

1 个答案:

答案 0 :(得分:1)

听起来你应该研究一些前端框架。在您的特定用例中,任何具有单向绑定的东西都可以工作(例如反应)。当然,任何具有双向绑定的东西都可以工作(有角度)。

Egghead.io做得非常好,一口大小的教程可以让你很快运行:https://egghead.io/browse/frameworks

编辑:

好吧,自从我上次做出反应以来已经过去了一年多,但我有一些想法可以提供帮助。

首先,反应是关于分离组件和将事物分解成更小的位。这个想法是你在顶层有一些状态变化,这些变化使用道具传播到嵌套组件。

我建议你有一个顶级组件来监听Firebase中的更改(我很长一段时间没用过FB),然后将这些组件发送到基于数据呈现的组件。我建议阅读Dan Abramov(Redux的创建者)撰写的这篇文章,该文章讨论智能与哑组件:https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0

同样,我有一段时间没有使用过反应,所以我将使用伪代码来描述你可能想要如何设计它。

顶级组件 此组件应该是您的应用与Firebase进行交互的唯一位置。您将在此处配置所有侦听器,以便在接收到新数据时,它只会传播到子组件。

constructor() {

    this.firebaseRef = firebase
        .database()
        .ref('logs');

    this.state = {
        logs: []
    };

    // when the table first loads, use the
    // firebase ref to get all the current data
    // and initialize/render the table. After this,
    // you should only be listening for when a new row
    // (or "log") is added. Pseudocode:
    firebase.database().ref('logs')
        .all()
        .then(logs => {
            // project all the logs into the model we need and set to 
            // component's row state
            this.state.logs = logs.map(logMapper);
        });
}

// takes in a log that you get from firebase and maps
// it to an object, modeled such that it contains all 
// the information necessary for a single table row
logMapper(log) {
    return {
        driver: log.child('Driver'),
        time: log.child('Time'),
        ...
    };
}

componentDidMount() {
    const logsRef = firebase
        .database()
        .ref('logs');

    firebaseRef.on('child_added', log => {
        this.state.logs.push(logMapper(log));
    });
}


render() {
    return (
        <table id="numbers">
            <thead>
                <th>Driver</th>
                <th>Coach</th>
                <th>Time</th>
                <th>Total People</th>
                <th>AM Train</th>
                <th>PM Train</th>
                <th>MEX</th>
                <th>Employees</th>
                <th>Seats Left</th>             
            </thead>
            <tbody>
                {this.state.logs.map(row => <TableRow rowData="logs" />}
            </tbody>
        </table>
    );
}

行组件 您有一个单独的组件,它通过props接收日志对象并呈现单行。

render() {
    return (
        <tr>
            <td>{this.props.rowData.driver}</td>
            <td>{this.props.rowData.coach}</td>
            <td>{this.props.rowData.time}</td>
            <td>{this.props.rowData.totalPeople}</td>
            <td>{this.props.rowData.amTrain}</td>
            <td>{this.props.rowData.pmTrain}</td>
            <td>{this.props.rowData.THEMEX}</td>
            <td>{this.props.rowData.Employees}</td>
            <td>{this.props.rowData.seatsLeft}</td> 
        </tr>
    );
}

上面的TableRow是一个哑组件的例子。它没有任何内部状态,也没有真正修改任何东西。它只需要通过道具获得它所呈现的内容。

同样,您必须将上面的示例视为伪代码,如果您尝试复制并运行它,它将无法工作。但希望这能让您深入了解如何设计反应中的组件。请记住,“一切都是一个组成部分”。

最后几个笔记:

  1. 组件更通用,它们更通用。理想 场景是你创建一个组件,如果你需要的话 稍后,您可以只使用已创建的组件 并稍加修改(或在最好的情况下插入) 情景,根本没有变化!)。所以,如果你发现自己需要一堆 在你的应用程序中的类似表格,你会想进一步概括我的 例。例如,firebase ref显式连接 “logs”集合,使此表组件仅对该一个对象类型有用。 您将要使父组件接收表 可以使用的名称或已初始化的firebase引用。 这样,组件就不会绑定到特定的firebase 表。映射函数也应该传入,如下所示 我的例子是硬编码来映射“日志”对象,你可能是 想要从firebase中获取其他类型。
  2. 我从阅读和弄乱中学到了很多东西,但老实说,我所采取的Udemy课程确实为我确定了所有概念:https://www.udemy.com/react-redux/ 我强烈建议你服用它,虽然你可能要等到Udemy有一个网站范围内的销售,你可以以10-20美元的价格购买该课程。我已经完成了他的几门课程,而且他们都非常物有所值。
  3. 祝你好运!