加载效果
如果使用 EasyUI tree 加载10000+项菜单项,全部加载出来耗时10s+,改为异步后,瞬间加载完成,极大提升用户体验。下图小圆圈是正在加载的菜单项效果。
Easyui tree 异步树
EasyUI官方文档
EasyUI 创建异步树形菜单 - 官方教程示例
树支持内置的异步加载模式,因此用户可以创建一个空的树,然后指定一个动态返回 JSON 数据的服务器端,用于根据需求异步填充树。
官方给了一个 PHP 的示例,这里就不贴代码了。
下面放上使用 Python Flask 创建异步树的代码示例:
表结构:
view层
@main.route('/basic_tree_fast/', methods=['GET', 'POST'])
@login_required
def basic_tree_fast():
result = Basic_menu.query.filter_by(isactive=True, pid=0).order_by(Basic_menu.id.asc()).all()
return render_template('basic_tree_fast.html', result=result)
@main.route('/basic_tree_async/', methods=['GET', 'POST'])
@login_required
def basic_tree_async():
"""
异步树
"""
param_dic = request.values.to_dict()
pid = convert.get_pid_from_dic(param_dic)
result = Basic_menu.query.filter_by(isactive=True, pid=pid).order_by(Basic_menu.id.asc()).all()
node_list = []
for one in result:
node = {}
state = convert.closed_or_open(convert.has_child(one.id))
node['id'] = one.id
node['text'] = one.name
node['state'] = state
node['attributes'] = one.url
node_list.append(node)
return json.dumps(node_list)
工具类
def has_child(id):
"""
判断某个菜单是否有子节点
"""
result = Basic_menu.query.filter_by(isactive=True, pid=id).all()
if result:
return True
else:
return False
def closed_or_open(has_child):
if has_child:
return 'closed'
else:
return 'open'
前端 HTML 代码
<div id="basic_menu" data-options="region:'west',title:'菜单',split:true" style="width:200px;">
<ul id="tree" class="easyui-draggable" style="padding: 10px" data-options="handle:'#title'"></ul>
</div>
<script type="text/javascript">
//异步加载树内容
$('#tree').tree({
url:'{{ url_for('main.basic_tree_async') }}',
checkbox: "true",
onlyLeafCheck:true,//仅叶子结点带有复选框
lines: true,
prerendered: false,// 提前渲染
onClick: function(node) { //拼装最后一个参数
// do something
}
}
});
// 清除勾选
function clean() {
var selected = $('#tree').tree('getChecked');
for (var i = 0; i < selected.length; i++) {
$('#tree').tree('uncheck', selected[i].target)
}
}
// 重新加载树
function reset() {
$("#tree").tree("reload");
}
</script>
一个小问题
使用异步加载树时,不知什么原因,官方提供的$("#tree").tree("collapseAll");
失效,无法一次性折叠全部节点。
因此使用$("#tree").tree("reload");
作为替代,这样做的缺点是折叠后不能保持原有已经勾选的框框。