/** * The Web UI Theme-v2.7.1 */ layui.define(["laytpl", "layer", "http"], function (exports) { // 构造函数 u - 主要接口 function View(e) { return new Template(e); } // 构造函数 t - 模板类 function Template(e) { this.id = e; this.container = layui.jquery("#" + (e || "LAY_app_body")); } // 引入依赖模块 var $ = layui.jquery, laytpl = layui.laytpl, layer = layui.layer, request = layui.http, setter = layui.setter, device = layui.device(), hint = layui.hint(), DEFAULT_CONTAINER_ID = "LAY_app_body"; // 加载动画 View.loading = function (container) { container.append( this.elemLoad = $('') ); }; // 移除加载动画 View.removeLoad = function () { this.elemLoad && this.elemLoad.remove(); }; // 退出登录 View.exit = function (callback) { // setter.request.tokenName 当前为 false,不能作为键,否则等于没清理。 // 统一清空本应用命名空间下的登录态与菜单缓存(对齐 layuiadmin 的退出清理)。 var appName = setter.appName; ['access_token', 'refresh_token', 'menus', 'user', 'note'].forEach(function (key) { layui.data(appName, { key: key, remove: true }); }); callback && callback(); }; // AJAX 请求封装 View.req = function (options) { function getUrlInfo() { return setter.debug ? "
URL:" + options.url : ""; } var successCallback = options.success, errorCallback = options.error, requestConfig = setter.request, responseConfig = setter.response; // 处理请求数据 options.data = options.data || {}; options.headers = options.headers || {}; // 处理 token if (requestConfig.tokenName) { var data = typeof options.data === "string" ? JSON.parse(options.data) : options.data; options.data[requestConfig.tokenName] = requestConfig.tokenName in data ? options.data[requestConfig.tokenName] : layui.data(setter.appName)[requestConfig.tokenName] || ""; options.headers[requestConfig.tokenName] = requestConfig.tokenName in options.headers ? options.headers[requestConfig.tokenName] : layui.data(setter.appName)[requestConfig.tokenName] || ""; } // 清除原始回调 delete options.success; delete options.error; // 执行 AJAX 请求 return $.ajax($.extend({ type: "get", dataType: "json", success: function (response) { var statusCode = responseConfig.statusCode; if (response[responseConfig.statusName] == statusCode.ok) { // 成功 typeof options.done === "function" && options.done(response); } else if (response[responseConfig.statusName] == statusCode.logout) { // 退出登录 View.exit(); } else { // 错误处理 var errorMsg = [ "Error: " + (response[responseConfig.msgName] || "返回状态码异常"), getUrlInfo() ].join(""); View.error(errorMsg); } typeof successCallback === "function" && successCallback(response); }, error: function (xhr, status) { var errorMsg = [ "请求异常,请重试
错误信息:" + status, getUrlInfo() ].join(""); View.error(errorMsg); typeof errorCallback === "function" && errorCallback.apply(this, arguments); } }, options)); }; // 弹窗 View.popup = function (options) { var successCallback = options.success, skin = options.skin; delete options.success; delete options.skin; return layer.open($.extend({ type: 1, title: "提示", content: "", id: "LAY-system-view-popup", skin: "layui-layer-admin" + (skin ? " " + skin : ""), shadeClose: true, closeBtn: false, success: function (layero, index) { var closeBtn = $(''); layero.append(closeBtn); closeBtn.on("click", function () { layer.close(index); }); typeof successCallback === "function" && successCallback.apply(this, arguments); } }, options)); }; // 错误提示 View.error = function (content, options) { return View.popup($.extend({ content: content, maxWidth: 300, offset: "t", anim: 6, id: "LAY_adminError" }, options)); }; // Template 原型方法 // 渲染视图 Template.prototype.render = function (templatePath, params) { var self = this; layui.hash(); // 构建完整模板路径 templatePath = (setter.paths && setter.paths.views ? setter.paths : setter).views + templatePath + setter.engine; // 移除加载动画 $("#" + DEFAULT_CONTAINER_ID).children(".layadmin-loading").remove(); View.loading(self.container); // AJAX 获取模板 request.get(templatePath, { v: layui.cache.version }).then(function (html) { // 提取标题 var titleElem = $(html = "
" + html + "
").find("title"); var viewData = { title: titleElem.text() || (html.match(/([\s\S]*)<\/title>/) || [])[1], body: html }; titleElem.remove(); // 设置参数 self.params = params || {}; // 执行 then 回调 self.then && (self.then(viewData), delete self.then); // 解析模板 self.parse(html); View.removeLoad(); // 执行 done 回调 self.done && (self.done(viewData), delete self.done); }).catch(function (xhr) { View.removeLoad(); // 防止重复错误处理 if (self.render.isError) { return View.error("请求视图文件异常,状态:" + xhr.status); } // 根据状态码显示不同错误页面 if (xhr.status === 404) { self.render("template/tips/404"); } else { self.render("template/tips/error"); } self.render.isError = true; }); return self; }; // 解析模板 Template.prototype.parse = function (html, isRefresh, callback) { function processTemplate(templateInfo) { var compiledTemplate = laytpl(templateInfo.dataElem.html()); var renderData = $.extend({ params: self.params }, templateInfo.res); // 渲染并插入 DOM templateInfo.dataElem.after(compiledTemplate.render(renderData)); // 执行回调 typeof callback === "function" && callback(); // 执行 done 回调(可能是 JavaScript 代码) try { templateInfo.done && new Function("d", templateInfo.done)(renderData); } catch (error) { console.error(templateInfo.dataElem[0], "\n存在错误回调脚本\n\n", error); } } var self = this; var isObject = typeof html === "object"; var $html = isObject ? html : $(html); var templateElems = isObject ? html : $html.find("*[template]"); var hashData = layui.hash(); // 移除标题 $html.find("title").remove(); // 插入 HTML self.container[isRefresh ? "after" : "html"]($html.children()); // 设置参数 hashData.params = self.params || {}; // 处理所有模板元素 for (var i = templateElems.length; i > 0; i--) { (function () { var templateElem = templateElems.eq(i - 1); var doneCallback = templateElem.attr("lay-done") || templateElem.attr("lay-then"); // 解析模板属性 var urlTemplate = templateElem.attr("lay-url") || ""; var dataTemplate = templateElem.attr("lay-data") || ""; var headersTemplate = templateElem.attr("lay-headers") || ""; var url = laytpl(urlTemplate).render(hashData); var data = laytpl(dataTemplate).render(hashData); var headers = laytpl(headersTemplate).render(hashData); // 解析数据对象 try { data = new Function("return " + data + ";")(); } catch (error) { hint.error("lay-data: " + error.message); data = {}; } // 解析头部对象 try { headers = new Function("return " + headers + ";")(); } catch (error) { hint.error("lay-headers: " + error.message); headers = headers || {}; } // 如果有 URL,则发起请求 if (url) { View.req({ type: templateElem.attr("lay-type") || "get", url: url, data: data, dataType: "json", headers: headers, success: function (response) { processTemplate({ dataElem: templateElem, res: response, done: doneCallback }); } }); } else { // 直接处理模板 processTemplate({ dataElem: templateElem, done: doneCallback }); } })(); } return self; }; // 自动渲染 Template.prototype.autoRender = function (selector, callback) { var self = this; $(selector || "body").find("*[template]").each(function () { var $this = $(this); self.container = $this; self.parse($this, "refresh"); }); }; // 发送数据到模板 Template.prototype.send = function (template, data) { template = laytpl(template || this.container.html()).render(data || {}); this.container.html(template); return this; }; // 刷新 Template.prototype.refresh = function (callback) { var self = this; var nextTemplateId = self.container.next().attr("lay-templateid"); if (self.id == nextTemplateId) { self.parse(self.container, "refresh", function () { self.container.siblings('[lay-templateid="' + self.id + '"]:last').remove(); typeof callback === "function" && callback(); }); } return self; }; // 设置 then 回调 Template.prototype.then = function (callback) { this.then = callback; return this; }; // 设置 done 回调 Template.prototype.done = function (callback) { this.done = callback; return this; }; // 导出模块 exports("view", View); });