我目前正试图弄清楚如何使用RethinkDB中的更改Feed。
我有一个名为Calls
的表,在插入,删除和更新它时,我想流式传输更改。
现在,我有最初加载调用然后返回更改的函数:
r.db('test').table('Calls').run(function(err, cursor) {
if (err) throw err;
socket.emit('load calls', cursor);
});
r.db('test').table('Calls').orderBy({index: r.desc('call_number')})
.changes().run(function(err, cursor) {
if (err) throw err;
cursor.each(function(err, record) {
socket.emit('load calls', record);
});
});
在前端我将HTML附加到页面:
socket.on('load calls', function(docs) {
docs.map((call) => {
$('.calls-list').append(`
<tr id="call_${call.call_number}">
<td>${call.call_number}</td>
<td>${call.time}</td>
<td>${call.type}</td>
<td>${call.status}</td>
<td>
</td>
<td>${call.location} - ${call.location_cross}</td>
<td>${call.notes}</td>
<td><a id="update-call-${call.call_number}" href=""><i class="edit icon yellow text"></i></a> <a id="archive-call-${call.call_number}" href=""><i class="delete icon red text"></i></a></td>
</tr>
`);
}
});
这里的问题是附加的HTML或多或少是永久性的,并且是独立的&#34;来自数据库;我希望它是实时的,并且依赖于数据库更改源,就像在this video中一样。在这种情况下,数据库插入和orderBy是即时的。所以在我目前的问题中,如果有人想要删除一个调用,那么我必须发出一个套接字事件并通过引用该ID来删除相应的HTML元素。
答案 0 :(得分:1)
我不确定我是否正确理解了你的问题,但我会尝试解决一些问题。首先,调用更改源时返回的文档与调用r.db.table
(第一次调用)时的文档不同。您的第一个电话将返回所有&#34; Call&#34;来自数据库的文档,但更改源返回包含先前&#34; Call&#34;文件和新的&#34;电话&#34;文献。例如,当一个新的&#34; Call&#34;添加到数据库中,您将看到以下内容:
{
old_val: null,
new_val: {id: 1, call_number: x, time: y, ...}
}
更新现有的&#34;电话&#34;你会看到:
{
old_val: {id: 1, call_number: x, time: y, ...},
new_val: {id: 1, call_number: x2, time: y2, ...}
}
当&#34; Call&#34;删除你会看到:
{
old_val: {id: 1, call_number: x2, time: y2, ...},
new_val: null
}
您将不得不以不同方式处理每个场景。您可以通过检查每个文档中是否存在old_val和/或new_val来在前端执行此操作。像这样:
socket.on('load calls', function(docs) {
docs.map((call) => {
if (! call.old_val && ! call.new_val) {
// this is a call returned from from r.db.table, not the changefeed
// add call to the dom
}
else if (! call.old_val) {
call = call.new_val;
// this is a new call added to the db and returned from r.db.table.changes
// add call.new_val to the dom
}
else if (! call.new_val) {
// this is a delete - remove the row from the dom
}
else {
// this is an update - update the existing row
}
}
});
或者您可以在服务器上进行某种级别的过滤,并向客户端发出不同的事件。像这样:
r.db('test').table('Calls').orderBy({index: r.desc('call_number')})
.changes().run(function(err, cursor) {
if (err) throw err;
cursor.each(function(err, record) {
if (! record.old_val) {
// new call added
socket.emit('load calls', record);
}
else if (! call.new_val) {
// call deleted
socket.emit('delete calls', record);
}
else {
// call updated
socket.emit('edit calls', record);
}
});
});
然后在客户端上,您将订阅每个事件:
socket.on('load calls', function(docs) {
// add docs to dom
});
socket.on('edit calls', function(docs) {
// update docs in dom
});
socket.on('delete calls', function(docs) {
// delete docs from dom
});
希望这会有所帮助。仅供参考,我是您引用的视频/示例应用的作者:)感谢您的观看!