Bootstrap& DataTables:表格呈现两次

时间:2017-08-20 18:45:46

标签: twitter-bootstrap html-table datatables

请阅读以下内容"更新:2017年8月23日(20Hs)",我发现这个效果正在试验Flask,但它似乎只与DataTables和Bootstrap有关。

实现Flask应用程序我已经通过Pandas直接从CSV文件渲染了一个表读取数据,这没问题。

然后我决定使用DataTables来实现一些功能,例如滚动条/搜索/排序,以及稍后实现数据库时的其他更高级的功能。

# file structure
#
# /testapp
#   +--- /app
#   |     +------ /templates
#   |     |           +------ events.html
#   |     +------ __init__.py
#   |     |
#   |     +------ events.csv
#   |     
#   +---- run.py
#

我的__ init __ .py(我在其中呈现我的事件表)看起来像:

# file: __init__.py 
import pandas as pd

from flask import Flask, render_template
from flask_bootstrap import Bootstrap

app = Flask(__name__, static_path = '/static', static_url_path = '/static')

bootstrap = Bootstrap(app)

@app.route('/')
@app.route('/events')
def events():
    return render_template('events.html', page='events')

我的events.html模板如下:

{% extends "bootstrap/base.html" %}
{% block content %}

{% block scripts %}
    {{ super() }}
    <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/bs/dt-1.10.15/datatables.min.css"/>
    <script type="text/javascript" src="https://cdn.datatables.net/v/bs/dt-1.10.15/datatables.min.js"></script>

    <script>
        $(document).ready(function(){
            if ( !$.fn.dataTable.isDataTable( '#myTable' ) ) {
                $('#myTable').DataTable( {
                    scrollY: 270,
                    paging: false
                } );
            }
        });
    </script>
{% endblock scripts %}

<div class="bootstrap-iso">
    <div class="container-fluid">      
      <table border="1" class="dataframe " id="myTable">
      <thead>
        <tr style="text-align: right;">
          <th></th>
          <th>Event</th>
          <th>Next Shutdown</th>
          <th>Next Startup</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <th>1</th>
          <td>2017-08-20 15:06:18</td>
          <td>2017-08-20 16:06:00</td>
          <td>2017-08-21 07:30:00</td>
        </tr>
        <tr>
          <th>2</th>
          <td>2017-08-20 12:26:26</td>
          <td>2017-08-20 13:26:00</td>
          <td>2017-08-21 07:30:00</td>
        </tr>
      </tbody>
    </table>
    </div>
</div>

{% endblock %}

run.py文件如下所示:

from app import app
app.run(host='0.0.0.0', debug=False)

现在,当渲染事件页面时,我很快就会看到原始表格(没有DataTable),一秒钟后我看到表格再次呈现,但是采用DataTable格式。

有谁能解释一下我在这里做错了什么?

我应该使用DataTable提议的here等JavaScript源数据吗?

我正在使用Flask的Flask和Bootstrap,它使用jQuery版本v1.12.4。

非常感谢您提前帮助!

==============================

更新:2017年8月22日

使用Bootstrap时会出现此效果。当没有使用Bootstrap时(意味着:没有 &#34;扩展&#34; bootstrap / base.html&#34; &#34;在events.html中并设置相应的Datatables没有bootstrap)然后页面只更新一次,Datatables正确呈现。

我看到其他链接,如this(Bootstrap Issue),其中一个JS popover的函数被调用两次,我在质疑这是否是类似的问题...

我还使用最少的代码更新了文件(参见上面的 init .py和events.html)。

我也在DataTables论坛中发布了一个问题(Link

==============================

更新:2017年8月23日(20小时)

感谢DataTables论坛中的人们,通过实时数据表(link)可以在没有任何烧瓶或python文件的情况下重现效果!

转到此链接并添加以下行(来自Bootstrap CDN

进入HTML头:

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

现在,当您通过单击&#34; Run with JS&#34;来运行示例时按钮,您将首先看到HTML表格,然后是DataTable,

我正在使用DataTable 1.10.15,Bootstrap 3.3.7和JQuery 1.12.4

如果未使用Bootstrap,则不会发生此效果。

==============================

更新:2017年9月10日

对于我来说,通过使用新方法发布了关闭。请阅读下面2017年9月10日的帖子。

4 个答案:

答案 0 :(得分:1)

  

现在,在渲染事件页面时,我很快就会看到原始表格(不使用DataTable脚本),然后正确呈现了DataTable。

当我在上面评论时,我误解了这一点。这似乎不是Flask问题的大熊猫。

我把一个测试用例汇总到一个理论上,认为某些东西阻止了jQuery认为页面已经准备就绪,从而推迟了.DataFrame()的调用直到页面呈现之后。这就是你所看到的效果。 (我假设你从你重写的页面中提取jQuery。)

你没有显示jQuery所带来的影响,看起来你正在使用Bootstrap。你在拉其他JS吗?你可以发布那段代码吗?

查看DataTable文档时,唯一跳出来的是他们推荐的路径与您使用的路径不同(我查看的文档没有{ {1}}部分)。我在两者之间的结果略有不同。

答案 1 :(得分:0)

我现在正在使用另一种方法。我将表作为源数据(数组)传递给DataTables,HTML表只能正确呈现一次。

    @app.route('/')
    @app.route('/events')
    def events():
        with open("event.csv",'r') as dest_f:
            data_iter = csv.reader(dest_f, delimiter = ',')
            data = [data for data in data_iter]
        return render_template('events.html', page='events', html_table=data)

我不知道为什么另一种方式呈现两次,但是通过这种新方法,我得到了我想要的东西!

    <script>

        var dataSet = {{ html_table | safe }}

        $(document).ready(function(){
            if ( !$.fn.dataTable.isDataTable( '#myTable' ) ) {
                var table = $('#myTable').DataTable( {
                    "data" : dataSet,
                });
            }

        });

    </script>


...

    <table id="myTable" class="display nowrap dataframe" width="100%">
    </table>

答案 2 :(得分:0)

这对我不起作用。我删除所有元素并重新创建。

  $('.table-responsive').html('<table class="table table-bordered" id="dataTable" width="100%" cellspacing="0"></table>')
  $(document).ready(function() {  
    $('#dataTable').DataTable( {
        ajax: '/admin/users',
        columns: <%= raw @users_attrs.to_json %>
      });
  });

答案 3 :(得分:0)

我遇到了同样的问题。我找不到任何合适的解决方案。所以我用 DOM 操作作为一个 hack 修复了这个问题。

以下是我的表格:

<块引用>



  1. 在开始时通过 DOM 操作隐藏表格:
<块引用>
document.getElementById('inner-table').style.display = 'block';
  1. 然后,当表格呈现时,显示表格:
<块引用>
this.dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
          document.getElementById('client-table').style.display = 'block';
        });