layuiAdmin 的视图是一个“动静结合”的载体,除了常规的静态模板,你当然还可以在视图中存放动态模板,因此它可谓是焦点中的焦点。
定义模板
在视图文件中,通过下述规则定义模板:
<script type="text/html" template>
<!-- 动态模板碎片 -->
</script>
下面是一个简单的例子:
<script type="text/html" template>
当前 layuiAdmin 的版本是:{{ layui.admin.v }}
路由地址:{{ layui.router().href }}
</script>
在不对动态模板设定数据接口地址的情况下,它能读取到全局对象。但更多时候,一个动态模板应该是对应一个接口地址,如下所示
<script type="text/html" template lay-url="接口地址">
我叫:{{ d.data.username }}
{{# if(d.data.sex === '男'){ }}
公的
{{# } else { }}
母的
{{# } }}
</script>
模板中的 d 对应的是你接口返回的 json 转化后的一维对象,如:
{
"code": 0
,"data": {
"username": "贤心"
,"sex": "男"
}
}
那么,上述动态模板最终输出的结果就是:
我叫:贤心
公的
lay-url
用于绑定模板的数据接口地址,支持动态模板解析,如:
<script type="text/html" template lay-url="https://api.xxx.com?id={{ layui.router().search.id }}">
<!-- 动态模板碎片 -->
</script>
lay-type
用于设定模板的接口请求类型(默认:get),如:
<script type="text/html" template lay-url="接口地址" lay-type="post">
<!-- 动态模板碎片 -->
</script>
lay-data
用于定义接口请求的参数,其值是一个 JavaScript object 对象,同样支持动态模板解析,如:
<script type="text/html" template lay-url="接口地址" lay-data="{id: '{{ layui.router().search.id }}', type: 1}">
<!-- 动态模板碎片 -->
</script>
lay-headers
用户定义接口请求的 Request Headers 参数,用法与 lay-data 的完全类似,支持动态模板解析。
lay-done
接口请求完毕并完成视图渲染的回调脚本,里面支持写任意的 JavaScript 语句。事实上它是一个封闭的函数作用域,通过给 Function 实例返回的函数传递一个参数 d,用于得到接口返回的数据:
<script type="text/html" template lay-url="接口地址" lay-done="console.log(d);">
<!-- 动态模板碎片 -->
</script>
很多时候,你在动态模板中可能会放入一些类似于 layui 的 form 元素,而有些控件需要执行 form.render() 才会显示,这时,你可以对 lay-done 赋值一个全局函数,如:
<script type="text/html" template lay-url="接口地址" lay-done="layui.data.done(d);">
<div class="layui-form" lay-filter="LAY-filter-demo-form">
<input type="checkbox" title="复选框">
</div>
</script>
<!-- 注意:别看眼花了,下面可不是动态模板,而是 JS 脚本区域 -->
<script>
layui.data.done = function(d){
layui.use(['form'], function(){
var form = layui.form;
form.render(null, 'LAY-filter-demo-form'); //渲染该模板下的动态表单
});
};
</script>
如果模板渲染完毕需要处理过多的交互,我们强烈推荐你采用上述的方式定义一个全局函数赋值给 lay-done,会极大地减少维护成本。
无需担心该全局函数的冲突问题,该函数是一次性的。其它页面即便声明了一个同样的函数,也只是用于新的视图,丝毫不会对之前的视图造成任何影响。
layui.data.done 中的 done 可以随意命名,但需与 lay-done 的赋值对应上。
view(id)
获取指定容器,并返回一些视图渲染的方法,如:
//渲染视图,viewPath 即为视图路径
view('id').render(viewPath).then(function(){
//视图文件请求完毕,视图内容渲染前的回调
}).done(function(){
//视图文件请求完毕和内容渲染完毕的回调
});
//直接向容器插入 html,tpl 为 模板字符;data 是传入的数据。该方法会自动完成动态模板解析
view('id').send(tpl, data);
另外,render 方法支持动态传参,以用于视图内容接受。如:
admin.popup({
id: 'LAY-popup-test1'
,success: function(){
view(this.id).render('视图文件所在路径', {
id: 123 //这里的 id 值你可以在一些事件中动态获取(如 table 模块的编辑)
});
}
});
那么,在视图文件中,你可以在动态模板中通过 {{ d.params.xxx }} 得到传入的参数,如:
<script type="text/html" template lay-url="http://api.com?id={{ d.params.id }}">
配置了接口的动态模板,且接口动态获取了 render 传入的参数:{{ d.params.id }}
</script>
<script type="text/html" template>
也可以直接获取:<input type="hidden" name="id" value="{{ d.params.id }}">
</script>
而如果是在 JS 语句中去获取模板传递过来的变量,可以借助动态模板的 lay-done 属性去实现,如:
<script type="text/html" template lay-done="layui.data.sendParams(d.params)">
</script>
然后在 JS 语句中通过执行动态模板 lay-done 中对应的方法得到对应的参数值:
<script>
//定义一个 lay-done 对应的全局方法,以供动态模板执行
layui.data.sendParams = function(params){
console.log(params.id) //得到传递过来的 id 参数(或其他参数)值
//通过得到的参数值,做一些你想做的事
//…
//若需用到 layui 组件,layui.use 需写在该全局方法里面,如:
layui.use(['table'], function(){
var table = layui.table;
table.render({
elem: ''
,url: 'url?id='+ params.id
});
});
};
</script>
在视图文件中,除了写 HTML,也可以写 JavaScript 代码。如:
<div id=“LAY-demo-hello”>Hello layuiAdmin</div>
<script>
layui.use('admin', function(){
var $ = layui.jquery;
admin.popup({
content: $('#LAY-demo-hello').html()
});
});
</script>
如果该视图对应的 JS 代码量太大,我们更推荐你在 controller 目录下新增一个业务模块,并在视图中直接 layui.use 去加载该模块。下面以控制台主页 index.html 为例:
<div>html区域<div>
<script>
//加载 controller 目录下的对应模块
/*
小贴士:
这里 console 模块对应 的 console.js 并不会重复加载,
然而该页面的视图可能会重新插入到容器,那如何保证脚本能重新控制视图呢?有两种方式:
1): 借助 layui.factory 方法获取 console 模块的工厂(回调函数)给 layui.use
2): 直接在 layui.use 方法的回调中书写业务代码,即:
layui.use('console', function(){
//同 console.js 中的 layui.define 回调中的代码
});
这里我们采用的是方式1。其它很多视图中采用的其实都是方式2,因为更简单些,也减少了一个请求数。
*/
layui.use('console', layui.factory('console'));
</script>
当视图被渲染后,layui.factory 返回的函数也会被执行,从而保证在不重复加载 JS 模块文件的前提下,保证脚本能重复执行。