我尝试创建一个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()
})
});
}
}
答案 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是一个哑组件的例子。它没有任何内部状态,也没有真正修改任何东西。它只需要通过道具获得它所呈现的内容。
同样,您必须将上面的示例视为伪代码,如果您尝试复制并运行它,它将无法工作。但希望这能让您深入了解如何设计反应中的组件。请记住,“一切都是一个组成部分”。
最后几个笔记: