【问题标题】:Firebase - Prevent child_added when delete with limitToLastFirebase - 使用 limitToLast 删除时防止 child_added
【发布时间】:2016-11-03 14:37:48
【问题描述】:

我想建立迷你网络聊天 - 当查看站点时我设置显示 5 条消息,如果查看更多,您可以单击按钮。一切都很好,但是当我删除 1 个节点时,firebase 会自动添加最后一个节点,我该如何防止呢? 例如:我有节点 A、B、C、D、E、F、G。我已经加载了列表 C、D、E、F、G,但是当我一共删除 1 时,它会自动将 B 添加到列表中。

    <div id="messgesDiv">
    <center><h3>Message</h3></center>
  </div>
  <div style="margin-top: 20px;">
    <input type="text" id="nameInput" placeholder="Name">
    <input type="text" id="messageInput" placeholder="Message" data-id="">
    <input type="text" id="idproject" placeholder="ID Project">
  </div>
  <button id="delete">Delete Test</button>
  <button id="edit">Edit</button>
  <button id="loadmore">Load more</button>
  <button id="showlastkey">Show last key</button>

我的 javascript

$('#loadmore').click(function() {
    i = 0; old = first;
    myDataRef.orderByKey().endAt(first).limitToLast(6).on('child_added', function (snapshot){
      if( i == 0)
        first = snapshot.key();
      var message = snapshot.val();
      if(snapshot.key() != old)
        displayChatMessage(message.name, message.text, message.idproject, 'old');
      i++;
      console.log('myDataRef.orderByKey().endAt(first).limitToLast(6)');
    });
  });

  $("#messageInput").keypress(function (e){
    if(e.keyCode == 13){ //Enter
      var name = $("#nameInput").val();
      var text = $("#messageInput").val();
      var idproject = $("#idproject").val();
      if($("#messageInput").data("id")=='')
      {
        myDataRef.push({name: name, text: text, idproject: idproject});
      }
      else
      {
        myDataRef.child(key).update({name: name, text: text, idproject: idproject});
        $('#messageInput').attr('data-id', '');
      }
      $("#messageInput").val("");
    }
  });


    myDataRef.limitToLast(5).on('child_added', function (snapshot){
      if( i == 0)
        first = snapshot.key();
      var message = snapshot.val();
      displayChatMessage(snapshot.key(), message.name, message.text, message.idproject, 'new');
      i++;
      console.log(snapshot.key());
      console.log(' myDataRef.limitToLast(5)');
    });



  function displayChatMessage(key, name, text, idproject, status){
    //console.log(name + " -- " + text + " -- " +idproject);
    if( status == 'new')
    {
      $('<div/>', { 'data-id': key , 'class' : 'test'}).text(text + " - ").prepend($('<em/>').text(name+": " )).append("IdProject: "+idproject).appendTo($("#messgesDiv"));
      $("#messgesDiv")[0].scrollTop = $("#messgesDiv")[0].scrollHeight;
    }
    else
    {
      $('<div/>', { 'data-id': key , 'class' : 'test'}).text(text + " - ").prepend($('<em/>').text(name+": " )).append("IdProject: "+idproject).insertAfter($("center"));
      $("#messgesDiv")[0].scrollTop = $("#messgesDiv")[0].scrollHeight;
    }
  }

  $('#delete').click(function() {
    myDataRef.child(key).remove();
    $('#messgesDiv').filter('[data-id="'+key+'"]').remove();
  });

【问题讨论】:

    标签: javascript firebase firebase-realtime-database


    【解决方案1】:

    Firebase 限制查询就像数据之上的视图。因此,如果您为 5 条最新消息创建查询,Firebase 客户端将确保您始终拥有 5 条最新消息。

    假设您从这些消息开始:

    message1
    message2
    message3
    message4
    message5
    

    现在如果你添加一个消息6,你会得到:

    child_removed message1
    child_added message6
    

    这样您的整体本地视图变为:

    message2
    message3
    message4
    message5
    message6
    

    相反,当您再次删除消息 6 时,您会收到以下事件:

    child_removed message6
    child_added message1 (before message2)
    

    这样您就可以更新 UI 并再次获得正确的列表。

    无法更改 API 的这种行为。因此,如果您想以不同的方式处理这种情况,则必须在客户端代码中执行此操作。

    您的代码目前仅处理child_added。如果您为child_removed 添加了处理程序,您会发现您可以轻松地使用户界面与数据保持同步。

    或者,您可以通过将要添加的消息的键与 DOM 中已经存在的键进行比较来检测消息是否已经在您的 UI 中:

    function displayChatMessage(key, name, text, idproject, status){
      var exists = $("div[data-id='" + key + "']").length;
      if (status == 'new' && !exists) {
        $('<div/>', { 'data-id': key , 'class' : 'test'}).text(text + " - ").prepend($('<em/>').text(name+": " )).append("IdProject: "+idproject).appendTo($("#messgesDiv"));
        $("#messgesDiv")[0].scrollTop = $("#messgesDiv")[0].scrollHeight;
      }
      else {
        $('<div/>', { 'data-id': key , 'class' : 'test'}).text(text + " - ").prepend($('<em/>').text(name+": " )).append("IdProject: "+idproject).insertAfter($("center"));
        $("#messgesDiv")[0].scrollTop = $("#messgesDiv")[0].scrollHeight;
      }
    }
    

    【讨论】:

    • 有没有更好的方法来解决这个问题?我知道处理程序总是试图保持相同数量的消息,但这只有在你总是想在屏幕上保持该数量的消息时才有效。在几乎所有情况下,您已经加载了较旧的消息并继续添加更多消息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-19
    • 1970-01-01
    • 1970-01-01
    • 2021-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多