【问题标题】:Meteor with DataTables: Meteor._atFlush TypeError带有数据表的流星:Meteor._atFlush TypeError
【发布时间】:2013-02-17 19:58:00
【问题描述】:

我正在尝试将 DataTables(通过 mrt add datatables)与 Meteor 一起使用。我尝试将$('#mytableid').dataTable() 添加到Meteor.subscribe 回调、Meteor.autorunMeteor.startupTemplate.mytemplate.rendered 中——所有这些都会导致以下异常和No data available in table 消息。

任何指针?

    Exception from Meteor._atFlush: TypeError: Cannot call method 'insertBefore' of null
        at http://localhost:3000/packages/liverange/liverange.js?bc1d62454d1fefbec95201344b27a7a5a7356293:405:27
        at LiveRange.operate (http://localhost:3000/packages/liverange/liverange.js?bc1d62454d1fefbec95201344b27a7a5a7356293:459:11)
        at LiveRange.replaceContents (http://localhost:3000/packages/liverange/liverange.js?bc1d62454d1fefbec95201344b27a7a5a7356293:403:17)
        at http://localhost:3000/packages/spark/spark.js?c202b31550c71828e583606c7a5e233ae9ca50e9:996:37
        at withEventGuard (http://localhost:3000/packages/spark/spark.js?c202b31550c71828e583606c7a5e233ae9ca50e9:105:16)
        at http://localhost:3000/packages/spark/spark.js?c202b31550c71828e583606c7a5e233ae9ca50e9:981:9
        at http://localhost:3000/packages/deps/deps-utils.js?f3fceedcb1921afe2b17e4dbd9d4c007f409eebb:106:13
        at http://localhost:3000/packages/deps/deps.js?1df0a05d3ec8fd21f591cfc485e7b03d2e2b6a01:71:15
        at Array.forEach (native)
        at Function._.each._.forEach (http://localhost:3000/packages/underscore/underscore.js?47479149fe12fc56685a9de90c5a9903390cb451:79:11)

更新: 可能与 this issue 相关,找到的最佳解决方案是为每一行调用 dataTable() ——在这种情况下并不理想,考虑到非常大量的行。

【问题讨论】:

    标签: datatables meteor


    【解决方案1】:

    Dror 的回答肯定是正确的开始。以下是我目前看到的最佳做法:

    HTML

    <template name="data_table">
        {{#constant}}
            <table class="table table-striped" id="tblData">
            </table>
        {{/constant}}
    </template>
    

    JS:

    Template.data_table.created = function() {
        var _watch = Collection.find({});
        var handle = _watch.observe({
            addedAt: function (doc, atIndex, beforeId) {
                $('#tblData').is(":visible") && $('#tblData').dataTable().fnAddData(doc);
            }
            , changedAt: function(newDoc, oldDoc, atIndex) {
                $('#tblData').is(":visible") && $('#tblData').dataTable().fnUpdate(newDoc, atIndex);
            }
            , removedAt: function(oldDoc, atIndex) {
                $('#tblData').is(":visible") && $('#tblData').dataTable().fnRemove(atIndex);
            }
        });
    };
    
    Template.data_table.rendered = function () {
    
        if (!($("#tblData").hasClass("dataTable"))) {
            $('#tblStudents').dataTable({
                "aaSorting": []
                , "sDom": "<'row-fluid'<'span6'l><'span6'f>r>t<'row-fluid'<'span6'i><'span6'p>>"
                , "sPaginationType": "bootstrap"
                , "oLanguage": {
                    "sLengthMenu": "_MENU_ records per page"
                }
                , "aoColumns": [
                    { "sTitle": "First Data", "mData": function (data) { return data.firstData },
                ]
            });
    
            $('#tblData').dataTable().fnClearTable();
            $('#tblData').dataTable().fnAddData(Collection.find().fetch());
        }
    };
    

    【讨论】:

    • 有趣。让我试一试。我有点沮丧,没有更直接的方法可以做到这一点。
    • 我会注意到它在大型数据集上速度非常慢。
    • 这种方法似乎普遍有效,但有一些变化,请看下面我的回答。
    【解决方案2】:

    由于 Meteor 是响应式的,因此您需要先创建一个空表,然后再添加行。

    创建表:

    $('#myTable').dataTable( {
        "aoColumns": cols, //the column titles
        "sDom": gridDom
    } );
    

    添加行应该类似于:

     var myCursor = myCollection.find({});
     var handle = myCursor.observe({
      added: function (row) {
       //Add in here the data to the table
      },
    

    });

    【讨论】:

      【解决方案3】:

      已回答的方法仍然有效,但需要在两年后进行一些更改。

      1. 不再有恒定的东西。
      2. 不要放置空表,而是放置 thead 而不是 tbody。这样,列就被正确定义了。
      3. 将观察者放入 onRendered(不再渲染)而不是 onCreated(不再创建)。否则,表格只会在第一次创建时填充,而不是在您返回时填充。
      4. 不需要 onRendered 上的 clear 和 fill 方法。
      5. 在观察方法中,确保添加的是数组而不是对象。否则 fnAdd 无法呈现内容
      6. fnRemove 已不复存在。改用 fnDeleteRow
      7. 我不确定是否需要“可见检查”。你也删了好像没问题,所以我删了。

      有了上面的注释,下面是代码:

      Template.creamDealsList.onRendered(function () {
         if (!($("#tblData").hasClass("dataTable"))) {
            $('#tblStudents').dataTable({
              // Those configuration are not really important, use it as they are convenient to you
              "aaSorting": []
              , "sDom": "<'row-fluid'<'span6'l><'span6'f>r>t<'row-fluid'<'span6'i><'span6'p>>"
              , "sPaginationType": "bootstrap"
              , "oLanguage": {
                  "sLengthMenu": "_MENU_ records per page"
              }
              , "aoColumns": [
                  { "sTitle": "First Data", "mData": function (data) { return data.firstData },
              ]
          });
         }
        var _watch = Collection.find({});
        var convertDocToArray = function (doc) {return [doc._id, doc.name]}
        var handle = _watch.observe({
          addedAt: function (doc, atIndex, beforeId) {
              $('#tblData').dataTable().fnAddData(convertDocToArray(doc));
          }
          , changedAt: function(newDoc, oldDoc, atIndex) {
              $('#tblData').dataTable().fnUpdate(convertDocToArray(newDoc), atIndex);
          }
          , removedAt: function(oldDoc, atIndex) {
              $('#tblData').dataTable().fnDeleteRow(atIndex);
          }
        });
      })
      

      简单的 HTML 应该是这样的:

      <template name="data_table">
          <table class="table table-striped" id="tblData">
              <thead>
                  <th>Id</th>
                  <th>Name</th>
              </thead>
          </table>
      </template>
      

      这至少对我有用。我不再看到刷新错误。而且,当您稍后渲染时,有时,数据表中没有可用的数据消息并且该消息也消失了。

      【讨论】:

        【解决方案4】:

        这是我在 Meteor 中使用 CoffeeScript 和 HTML 实现的 dataTables。它可以工作,而且更简单,但可能比现有的大型表答案效率低(但在我的情况下它很快)。

        模板函数

        Template.dashboard.rendered = ->
        
          # Tear down and rebuild datatable
          $('table:first').dataTable
            "sPaginationType": "full_numbers"
            "bDestroy": true
        

        HTML

        <template name="dashboard">
          <table class="table table-bordered" id="datatable_3" style="min-width:1020px">
            <thead>
              <!-- code removed to save space -->
            </thead>
            <tbody id="previous-jobs-list">
              {{#each jobs}}
                {{> jobRow}}
              {{/each}}
            </tbody>
          </table>
        </template>
        
        <template name="jobRow">
          <tr>
            <td><a href="/jobs/{{number}}">{{number}}</a></td>
            <td>{{normalTime date}}</td>
            <!-- more code removed to save space -->
          </tr>
        </template>
        

        dashboard.jobs 是集合上的简单 .find(...)。

        【讨论】:

        • 这可能在当时使用,但现在它可以解决问题。在第一次渲染时,由于没有内容,table 显示一条未找到数据的消息,当它继续渲染时,您也会看到内容,并且以后不会删除“no data”消息。
        猜你喜欢
        • 2016-07-24
        • 1970-01-01
        • 2019-04-08
        • 1970-01-01
        • 2014-03-02
        • 2015-08-10
        • 2018-01-18
        • 2016-12-15
        • 1970-01-01
        相关资源
        最近更新 更多