Python 全栈系列91 - 使用Flask+DataTables+Mongo搭建交互式表格2 - 动态创建表格

本文详细介绍了如何构建一个可复用的前后端交互框架,用于快速创建动态表格。主要内容包括前端H5元素、JavaScript、Flask视图的结合使用,以及动态交互表格的实现。通过创建蓝图、定义页面结构、处理数据交互和表格操作,实现了数据的增删改查功能。此外,还讨论了数据视图返回内容、页面JS以及数据库操作的相关细节。
摘要由CSDN通过智能技术生成

说明

稍微修正、梳理一下之前的的做法
目标:可以快速的重复使用,基本上前后端的表格交互我就用这一套了。

内容

1 三部分功能

前后端设计到三部分:

  • 1 H5 元素: 前端页面的展示效果
  • 2 Javascript:前后端的交互桥梁
  • 3 View(Flask):使用python基本对象和DataFrame与JS通信。

假设现在是要做某个页面(view.html), 梳理一下前后端的代码,Flask的view函数产生内容,然后render_template填充内容。

2 view.html

某个功能的页面从所在的app导入索引页面(这样就不必单独设置导航条),新增的页面知识扩充了script,并且覆盖刷新的pagecontent。

{% extends '/app/index.html'%}

{%block head%} 
{{super()}}

{%for some_script in myscrips%}
{{some_script|safe}}
{%endfor%}

{%endblock%}



{%block pagecontent%}

{%for row_content in rows%}
{{row_content|safe}}
{%endfor%}

{%endblock%}

3 view.py

将需要的脚本和h5元素一个个的写好,‘串起来’就可以了

@app.route('/view/', methods=['GET', 'POST'])
@login_required
def view():
    # js脚本
    scripts = []
    script1 = render_template('/app/view_main.js')
    scripts.append(script1)
    ...

	# h5元素
    rows = []
    # 存储页面的临时存储变量
    global_vars = render_template('/app3/global_vars.html')
    rows.append(global_vars)

	...
    # 页面
    return render_template('/app3/view0011.html', rows = rows, myscrips= scripts)

4 动态交互表格部分

这次的改进:根据js获取到的表格,动态的创建交互表格。

4.0 开始

在项目模板下创建一个文件夹,作为本次的应用。
然后:

  • 1 创建蓝图 __init__.py
  • 2 创建应用的主页 index.py
  • 3 创建应用主页的html框架 ‘app/index.html’

这个基础模板有三个地方需要关注:

  • 1 从最基础的网站模板扩展(已经定义很多bootstrap,jquery等资源)
{% extends 'base.html'%}
  • 2 覆盖写入导航条部分
...
{%block navcontent%}

<div class="container-fluid"><a xtype="a" class="navbar-brand" href="#">Base_Web</a>
    <ul xtype="h5_ele" class="navbar-nav navbar-top mr-5">
        <li xtype="h5_ele" class="nav-item"><a xtype="h5_ele" href="{{url_for('main.index')}}" class="nav-link">主页</a>
        </li>
        <li xtype="h5_ele" class="nav-item"><a xtype="h5_ele" href="{{url_for('main.view4')}}" class="nav-link">Datatables测试</a>
        </li>
        <li xtype="h5_ele" class="nav-item"><a xtype="h5_ele" href="{{url_for('main.view5')}}" class="nav-link">Markdown测试</a>
        </li>
...
        
    </ul>
</div>
{%endblock%}
  • 3 写一个应用的简介
{%block pagecontent%}
<!-- 空白行作为间隔 -->
<div class="m-5"></div>

<div class="row">
    <div class="col md-12">
        <div xtype="h5_ele" class="jumbotron">
            <h1>Memos</h1>
            <hr>
            <p> 备忘表格通知</p>
            <p> 重要点如下:</p>
            <p> 1. 使用动态方法创建交互式表格</p>
            <p> 2. 提供周期任务检查和提醒</p>
            <p> 3. 进行邮件和短信通知</p>
        </div>
    </div>
</div>

{%endblock%}

效果如下
在这里插入图片描述

4.1 构造应用主页面

同样准备一个h5页面和一个view。
view1.html
从欢迎页扩展,里面只定义了脚本和h5元素的列表循环。

{% extends '/memos/index.html'%}

{%block head%} 
{{super()}}

{%for some_script in myscrips%}
{{some_script|safe}}
{%endfor%}

{%endblock%}

{%block pagecontent%}



{%for row_content in rows%}
{{row_content|safe}}
{%endfor%}

{%endblock%}

view1.py

这里将根据实际情况逐个添加脚本/元素:

  • 1 如果是通用的部分,就放在templates/memos下面
  • 2 如果是该功能页的个性化部分,就放在templates/memos/view1/下面
from . import memos
from flask import render_template, current_app
from funcs import graph

@memos.route('/view1/', methods=['GET','POST'])
def view1():
    # js脚本
    scripts = []
	...
    rows = []
    ...
    # 存储页面的临时存储变量
    global_vars = render_template('/memos/global_vars.html')
    rows.append(global_vars)

    # 页面
    return render_template('/memos/view1.html', rows = rows, myscrips= scripts)

4.2 构造数据函数

假设某个视图会从数据库获取数据并形成一个dataframe。

  • 1 三套列名

    • 1 数据列:实际上真实需要编辑的数据列
    • 2 后端列:关于数据行的状态,前后端交互时使用。主要是序号、同步状态和操作类型。
    • 3 前端列:只用在前端的列,目前看主要就是checkbox那一列。
三套列名checkbox序号需要编辑的列同步状态操作类型
数据列XXYXX
后端列XYYYY
前端列YYYYY
  • 2 将dataframe转为h5
dataframe 数据
         x1        x2         y
0  0.066579  0.679521  2.017807
1  0.859233  0.663780 -0.307603

这个函数会把df转换为html,并将数据列变为后端列

# 从df生成datatables需要的html
def df2dttable(some_df, keep_cols,replace_str):
    some_df1 = some_df[keep_cols]
    # 序号
    some_df1.insert(0, '序号', range(len(some_df1)))
    # checkbox
    some_df1.insert(0, '','')
    # 编辑类型
    some_df1.insert(len(some_df1.columns),'操作类型','查询')
    # 输出html
    return some_df1.to_html(index=False).replace('''class="dataframe"''', replace_str)

这里还是需要使用一个小函数来创建需要替换的元素属性,默认生成的class不是我们想要的,也没有id属性。

# 替换h5元素属性
def a_replace_h5attr(para_dict):
    res = ''
    for k in para_dict.keys():
        res += ''' %s="%s" ''' %(k, para_dict[k])
    return res 

使用的时候,这样就完成了df向普通的table转换,并且加上了id

...
    df = pd.DataFrame(np.random.randn(2,3), columns=['x1','x2', 'y'])

    para_dict = {'id':'memo_table', 'class':'display'}
    replace_str = a_replace_h5attr(para_dict)
    res_h5 = df2dttable(df, list(df.columns), replace_str)
...
<table border="1"  id="memo_table"  class="display" >
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>序号</th>
      <th>x1</th>
      <th>x2</th>
      <th>y</th>
      <th>操作类型</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td></td>
      <td>0</td>
      <td>0.066579</td>
      <td>0.679521</td>
      <td>2.017807</td>
      <td>查询</td>
    </tr>
    <tr>
      <td></td>
      <td>1</td>
      <td>0.859233</td>
      <td>0.663780</td>
      <td>-0.307603</td>
      <td>查询</td>
    </tr>
  </tbody>
</table>

4.3 交互式表格h5模板

这个模板大致分为三部分:

  • 1 按钮组。提供对表格的增删改。
  • 2 模态框。增加,修改行数据是通过模态框来编辑的。
  • 3 数据表格。将上面的dataframe数据“灌”进去就可以了。
<!-- 空白行作为间隔 -->
<div class="m-5"></div>



<div class="row">

<div class="col md-12">
    <h3>{{title}}</h3><hr>
</div>
</div>


<div class="row" id="{{row_id}}_btn">


    <div class="col md-12" id="{{col_id}}_btn">

        <!-- ======================> 按钮组 -->
        <div class="btn-group operation">
            <button id="{{col_id}}_btn_add" type="button" class="btn btn-primary  mx-2" data-toggle="modal">
                <!-- bootstrap4已经不默认提供图标了,而是分开了,需要在别的地方下载,并使用方法也有所变化 -->
                <i class="fa fa-plus" aria-hidden="true">新增</i>
            </button>

            <button id="{{col_id}}_btn_edit" type="button" class="btn btn-info mx-2">
                <i class="fa fa-pencil" aria-hidden="true">修改</i>
            </button>

            <button id="{{col_id}}_btn_delete" type="button" class="btn btn-danger  mx-2">
                <i class="fa fa-remove" aria-hidden="true">删除</i>
            </button>


            <button id="{{col_id}}_btn_submmit" type="button" class="btn btn-success mx-2">
                <i class="fa fa-paper-plane" aria-hidden="true">批量提交</i>
            </button>
        </div>

        <!-- ======================> 新增模态框 -->
        {{add_modal|safe}}
        <!-- ======================> 修改模态框 -->
        {{mod_modal|safe}}


    </div>
</div>

<!-- 空白行作为间隔 -->
<div class="m-2"></div>

<!-- 以下这部分是表格内容 -->
<div class="row" id="{{row_id}}">

    <div class="col md-12" id="{{col_id}}">

    

    </div>
</div>
4.3.1 动态的部分

因为行数据的修改是通过模态框进行的,因此需要对模态框中可编辑的元素进行声明:我希望直接通过给定df,根据其列名自动的生成模态框。

其中some_part的作用是区别一个页面中的多套动态表格。动态的核心部分使用了jinja的字典循环。

add_modal.html

<!-- 点击添加按钮的时候弹出的就是模态框,其本身看起来像一个网页  modal fade -> modal-dialog -> modal-content -> modal-header | ->addBookModal - footer -->
<div class="modal fade" id="{{some_part}}_addRow" role="dialog">

    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title">
                <!-- 直接用css来控制关闭模态框 -->
                <button type="button" class="close" data-dismiss="modal"><i class="fa fa-window-close" aria-hidden="true"> 添加数据</i></button>
                </h5>
            </div>

            <div id="{{some_part}}_addRowModal" class="modal-body">
                <!-- k是数据库的变量,v是显示在页面上的中文 -->
                <div class="form-horizontal">

                    {%for k,v in var_dict.items()%}
                    <div class="form-group">
                        <label for="{{some_part}}_add_{{k|e}}" class="col-sm-2 control-label">{{v|e}}:*</label>
                        <div class="col-sm-10">
                            <input class="form-control" id="{{some_part}}_add_{{k|e}}" type="text">
                        </div>
                    </div>

                    {% endfor%}
                </div>
            </div>


            <div class="modal-footer">
                <div class="center-block">
                    <button id="{{some_part}}_cancelAdd" type="button" class="btn btn-warning" data-dismiss="modal">取消</button>
                    <button id="{{some_part}}_addRowsInfo" type="button" class="btn btn-success" data-dismiss="modal">保存</button>
                </div>
            </div>
        </div>
    </div>
</div>

修改模态框是类似的
mod_modal.html

<div class="modal fade" id="{{some_part}}_editRow" role="dialog">

    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title">
                <!-- 直接用css来控制关闭模态框 -->
                <button type="button" class="close" data-dismiss="modal"><i class="fa fa-window-close"
                        aria-hidden="true">修改数据</i></button>
                </h5>
            </div>

            <div id="{{some_part}}_editRowModal" class="modal-body">
                <div class="form-horizontal">
                    {%for k,v in var_dict.items()%}
                        <div class="form-group">
                            <label for="{{some_part}}_mod_{{k|e}}" class="col-sm-2 control-label">{{v|e}}:*</label>
                            <div class="col-sm-10">
                                <input class="form-control" id="{{some_part}}_mod_{{k|e}}" type="text">
                            </div>
                        </div>
                    {% endfor%}
                </div>
            </div>



            <div class="modal-footer">
                <div class="center-block">
                    <button id="{{some_part}}_cancelEdit" type="button" class="btn btn-warning"
                        data-dismiss="modal">取消</button>
                    <button id="{{some_part}}_saveEdit" type="button" class="btn btn-success"
                        data-dismiss="modal">保存</button>
                </div>
            </div>
        </div>
    </div>
</div>

4.4 数据视图返回的内容

此时的数据视图可以返回动态表格所需的所有内容了。注意数据表格的数据部分用memo_table作为id, 而动态模态框部分用memo_dynamic_col作为id。

@memos.route('/view0002/', methods=['GET','POST'])
def view0002():
    web1 = dm.WebMsg('view0002') 
    df = pd.DataFrame(np.random.randn(2,3), columns=['x1','x2', 'y'])
    df['_update_status'] =1
    # print(df)

    # 数据框部分
    para_dict = {'id':'memo_table', 'class':'display'}
    replace_str = a_replace_h5attr(para_dict)
    res_h5 = df2dttable(df, list(df.columns), replace_str)

    # print(res_h5)

    # 模态框部分
    # 原始的列名。不可以下划线开头
    original_cols = [x for x in list(df.columns) if not x.startswith('_')]
    # 模态框显示的列名:这次使用原名,根据需要可以更改
    showname_cols = [x for x in list(df.columns) if not x.startswith('_')]
    memo_dynamic_dict = dict(zip(df.columns, df.columns))
    # 动态参数化-新增模态框
    memo_dynamic_add_modal_content = render_template('/memos/interactive_table/add_modal.html', 
                                some_part ='memo_dynamic_col', var_dict = memo_dynamic_dict)
    # 动态参数化-修改模态框
    memo_dynamic_mod_modal_content = render_template('/memos/interactive_table/mod_modal.html', 
                                some_part ='memo_dynamic_col', var_dict = memo_dynamic_dict)

    # 交互式表格
    interactive_table_content = render_template('/memos/interactive_table/interactive_table.html',title='备忘',
                                                row_id='memo_dynamic_row', col_id='memo_dynamic_col',
                                                add_modal = memo_dynamic_add_modal_content,
                                                mod_modal = memo_dynamic_mod_modal_content)


    interactive_table_h5 = interactive_table_content

    the_data = {'res_h5':res_h5, 'interactive_table_h5':interactive_table_h5,
                'edit_cols':original_cols,'edit_cols_name':showname_cols }

    web1.status = True 
    web1.msg = 'ok'
    web1.data = json.dumps(the_data)
    print(res_h5)
    return jsonify(web1.to_dict())

在这里插入图片描述

4.5 页面的js

现在有了视图函数提供数据,也有了前端h5元素承载数据,要“动”起来还需要js。js可以分为定义部分和运行部分,类似于python的def xxx定义函数,然后if __name__=='__main__'来执行一个脚本。

也就是说,主页面的js调用view0002这个视图生成的内容填充生成具体的内容。

4.5.1 初次静态载入

发现零零碎碎的js还比较多,下面就梳理必要的几个js
main.js 页面载入后发起一个请求,从view0002获取初始的数据

<script>
// 载入页面后执行
$(function(){

// 这里不需要参数,仅仅是为了保持结构
para_dict = {}
para_dict_str = JSON.stringify(para_dict)
target_url = '/memos/view0002/'

general_ajax_post(target_url, para_dict_str, success_func= success_memo_table)

})
</script>

发起一个ajax请求,可以指定成功后的函数
general_ajax_post.js

<script>
function null_func(x){}


function general_ajax_post(target_url, para_dict_str, 
                            success_func = null_func, 
                            error_func = null_func,
                            timeout = 3000) {
$.ajax({
    type:'POST',
    url:target_url, 
    data:para_dict_str,
    timeout:timeout,
    processData:false,
    contentType:'application/json',
    success:function(res_data){
        success_func(res_data)
    },
    error:function(){
        error_func()
    }
})   
}
</script>

成功后执行的脚本
success_memo_table.js

<script>
function success_memo_table(res_data) {
    cur_status = res_data.status 
    cur_msg = res_data.msg 
    cur_data = JSON.parse(res_data.data)

    cur_interactive_table_h5 = cur_data.interactive_table_h5
    cur_data_res_h5 = cur_data.res_h5
    cur_data_edit_cols = cur_data.edit_cols
    cur_data_edit_cols_name = cur_data.edit_cols_name

    // 模态框部分更新
    $('#memo_dynamic_table_col').html(cur_interactive_table_h5)

    if(cur_status){
        $('#memo_table_col').empty()
        $('#memo_table_col').html(cur_data_res_h5)
        $('#memo_table').DataTable()
        format_table_col('memo_table', 0, format_checkbox)

        // 增加选择样式
        $('#memo_table').find('tbody').find('tr').attr('onclick','select_element_toggle(this)')
        // 列数 - 格式化倒数第二列
        col_num = $('#memo_table').find('tbody').find('tr').eq(0).find('td').length
        format_table_col('memo_table', col_num-2, vmap)
    }
    else{
        prepend_ele('#global_vars', warn_msg('表格数据加载失败'))
    }
}
</script>

在这里插入图片描述

4.5.3 增删改按钮的动作

success_memo_table.js中,如果动态表格返回有值,那么增加这些按钮的动作

4.5.3.1 增
        // --------> 按钮的交互
        $('#memo_dynamic_col_btn_add').click(function(){
            $('#memo_dynamic_col_addRow').modal()
        })

在这里插入图片描述
点击保存按钮时,要把数据添加到表格末端。通过把新增模态框中的数据读过来附加到最后一行

        // 增加行
        $('#memo_dynamic_col_addRowsInfo').on('click', function(){
            add_row_func('memo_table','memo_dynamic_col_addRowModal','memo_dynamic_col' ,cur_data_edit_cols)
        })
// 对应的函数
<script>
function add_row_func(table_id, modal_id,part_id,edit_cols){
    // alert(table_id)
    the_table =  $('#'+table_id).DataTable()
    // 行号
    row_num = $('#' + table_id).find('tbody').find('tr').length
    // 将行的值放入列表
    addRowInfos = []
    // 推入固定的第一、第二列
    addRowInfos.push('<input type="checkbox" checked=true>');
    addRowInfos.push(row_num);
    // 如果模态框内容不为空,那么执行推入
    alert('sss')
    if($('#'+modal_id).find('input')!==''){
        // 推入编辑列
        for(i=0;i<edit_cols.length;i++){
            col_id = '#' + part_id + '_add_' + edit_cols[i]
            if($(col_id).val()){
                addRowInfos.push($(col_id).val())
            }
            else{
                addRowInfos.push(' ')
            }
        }
    // 倒数第二列
    addRowInfos.push(vmap(0))
    // 最后一列
    addRowInfos.push('新增')

    // 写入表
    the_table.row.add(addRowInfos).draw()

    }
    else{
        alert('不能为空')
    }


}


</script>

在这里插入图片描述

4.5.3.2 改

改按钮需要读取现有表的内容

        // 修改
        $('#memo_dynamic_col_btn_edit').click(function(){
            call_edit_modal('memo_table','memo_dynamic_col')
        })

对应的call_edit_modal.js如下

<script>
function call_edit_modal(table_id,part_id){
    the_table = $('#'+table_id).DataTable()
    if(the_table.rows('.selected').data().length){
        // 唤起模态框
        $('#'+part_id + '_editRow').modal()
        // 行内数据
        rowData = the_table.rows('.selected').data()[0]
        // 模态框数据
        inputs = $('#' + part_id + '_editRowModal').find('input')
        for(var i=0;i<inputs.length;i++){
            $(inputs[i]).val(rowData[i+2])
        }
    }
    else{
        alert('未选中行')
    }
}
</script>

在这里插入图片描述
对于保存按钮(memo_dynamic_col_saveEdit)的动作

        // 修改行保存
        $('#memo_dynamic_col_saveEdit').on('click', function(){
            edit_row_func('memo_table','memo_dynamic_col' ,cur_data_edit_cols)
        })

<script>
function edit_row_func(table_id, part_id,edit_cols){
    curTr = $('#'+table_id).find('input[type="checkbox"]:checked').first().closest('tr')
    tds  =  $(curTr).find('td')
    // alert('working')
    for(i=0;i<edit_cols.length;i++){
        new_td_content = $('#' + part_id +'_mod_' +edit_cols[i]).val()
        $(tds[i+2]).html(new_td_content)
    }
    // 倒数第二列
    $(tds[tds.length-2]).html(vmap(0))
    // 倒数第一列
    $(tds[tds.length-1]).html('修改')
}


</script>

在这里插入图片描述

4.5.3.3 删

不必唤起模态框,因此没有保存按钮

        // 删除
        $('#memo_dynamic_col_btn_delete').click(function(){
            delete_row_func('memo_table')
        })

<script>
function delete_row_func(table_id){
    $('#'+table_id).find('input[type="checkbox"]:checked').each(function(){
        tds = $(this).closest('tr').children('td')
        last_one = tds.length -1 
        last_two = last_one -1 
        $(tds).eq(last_one).html('删除')
        $(tds).eq(last_two).html(vmap(0))
    })
}


</script>

在这里插入图片描述

4.5.2 批量提交

获取勾选的数据

<script>
function updated_rows_data(table_id) {
    //alert(table_id)
    data_list = []
    $('#'+table_id).find('input[type="checkbox"]:checked').each(function(){
        curTr = $(this).closest('tr')
        tem_list = []
        for(i=1;i<curTr.children('td').length;i++){
            the_value = $(curTr).children('td').eq(i).text()
            tem_list.push(the_value)
        }
        data_list.push(tem_list)
    })
    return data_list
}
</script>

提交到后台的数据类似

{'data': [['0', '-0.756943', '-0.786949', '0.497998', '', '查询']], 
'meta': {'edit_cols': ['x1', 'x2', 'y'], 'edit_cols_name': ['x1', 'x2', 'y']}}

这是和后台交互最重要的一步

获取checkbox 选中的行向后台提交

获取选中的行

<script>
function updated_rows_data(table_id) {
    //alert(table_id)
    data_list = []
    $('#'+table_id).find('input[type="checkbox"]:checked').each(function(){
        curTr = $(this).closest('tr')
        tem_list = []
        for(i=1;i<curTr.children('td').length;i++){
            the_value = $(curTr).children('td').eq(i).text()
            tem_list.push(the_value)
        }
        data_list.push(tem_list)
    })
    return data_list
}
</script>

success_memo_table.js中获取checkbox选中的行,向目标/memos/view0003/发起提交请求,并约定使用success_memo_table_submit函数处理返回的数据。

        // 提交
        $('#memo_dynamic_col_btn_submmit').on('click', function(){

            data_list = updated_rows_data('memo_table')
            //alert(data_list[0])
            target_url = '/memos/view0003/'

            para_dict = {}
            para_dict['data'] = data_list
            para_dict['meta'] = {}
            para_dict['meta']['edit_cols'] = cur_data_edit_cols_name
            para_dict['meta']['edit_cols_name'] = cur_data_edit_cols_name
            para_dict_str = JSON.stringify(para_dict)
            general_ajax_post(target_url, para_dict_str,success_func=success_memo_table_submit)
        })
后台处理后返回前端

后端要和数据库交互,进行数据库更新,然后返回更新后的状态。下面构造了一个简单的例子,实际使用时用真实的数据库连接替代就可以了。

@memos.route('/view0003/', methods=['GET','POST'])
def view0003():
    web1 = dm.WebMsg('view0003') 
    input_dict = request.get_json()
    print(input_dict)

    edit_cols = input_dict['meta']['edit_cols']
    pre_cols = ['tmp_row_id']
    suf_cols = ['_update_status','opr_type']

    res_df = pd.DataFrame([['0', '-999', '-111', '222', '1', '查询']], columns = pre_cols + edit_cols + suf_cols)

    res_data = {}
    res_data['cols'] = pre_cols + edit_cols + suf_cols
    res_data['data_list'] = json.loads(res_df.to_json(orient='records'))
    res_data['update_status_col'] = '_update_status'
    res_data['row_id_col'] = 'tmp_row_id'

    web1.status = True 
    web1.msg = 'ok'
    web1.data = json.dumps(res_data)


    return jsonify(web1.to_dict())
前端使用返回的数据刷新表格
<script>
function success_memo_table_submit(res_data) {
    cur_status = res_data.status 
    cur_msg = res_data.msg 
    cur_data = JSON.parse(res_data.data)


    cur_data_list = cur_data['data_list']
    cur_cols = cur_data['cols']
    cur_update_status_col = cur_data['update_status_col']
    cur_row_id_col = cur_data['row_id_col']

    if(cur_status){
        // alert('here')
        for(i=0;i<cur_data_list.length;i++){
            tmp_row_id = cur_data_list[i][cur_row_id_col]
            cur_trs = $('#memo_table').find('tbody').find('tr')
            cur_tds = $(cur_trs).eq(tmp_row_id).children('td')
            for(j=0;j<cur_cols.length ;j++){
                col_name = cur_cols[j]
                if(col_name !== cur_update_status_col){
                    cur_tds.eq(j+1).html(cur_data_list[i][col_name])
                }
                else{
                    cur_tds.eq(j+1).html(vmap(cur_data_list[i][col_name]))
                }
            }
        }
    }
    else{
        prepend_ele('#global_vars', warn_msg('项目提交数据刷新失败'))
    }

}
</script>

在这里插入图片描述

5 数据库的增删改操作

这块和普通的数据库读写略有差别,代码方面的内容还是有点多,另起一章。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值