| /** | 
|   | 
|  @Name:layuiAdmin 视图模块 | 
|  @Author:贤心 | 
|  @Site:http://www.layui.com/admin/ | 
|  @License:LPPL | 
|      | 
|  */ | 
|   | 
| layui.define(['laytpl', 'layer'], function(exports){ | 
|   var $ = layui.jquery | 
|   ,laytpl = layui.laytpl | 
|   ,layer = layui.layer | 
|   ,setter = layui.setter | 
|   ,device = layui.device() | 
|   ,hint = layui.hint() | 
|    | 
|   //对外接口 | 
|   ,view = function(id){ | 
|     return new Class(id); | 
|   } | 
|    | 
|   ,SHOW = 'layui-show', LAY_BODY = 'LAY_app_body' | 
|    | 
|   //构造器 | 
|   ,Class = function(id){ | 
|     this.id = id; | 
|     this.container = $('#'+(id || LAY_BODY)); | 
|   }; | 
|    | 
|   //加载中 | 
|   view.loading = function(elem){ | 
|     elem.append( | 
|       this.elemLoad = $('<i class="layui-anim layui-anim-rotate layui-anim-loop layui-icon layui-icon-loading layadmin-loading"></i>') | 
|     ); | 
|   }; | 
|      | 
|   //移除加载 | 
|   view.removeLoad = function(){ | 
|     this.elemLoad && this.elemLoad.remove(); | 
|   }; | 
|    | 
|   //清除 token,并跳转到登入页 | 
|   view.exit = function(callback){ | 
|     //清空本地记录的 token | 
|     layui.data(setter.tableName, { | 
|       key: setter.request.tokenName | 
|       ,remove: true | 
|     }); | 
|      | 
|     //跳转到登入页 | 
|     //location.hash = '/user/login';  | 
|     callback && callback(); | 
|   }; | 
|    | 
|   //Ajax请求 | 
|   view.req = function(options){ | 
|     var that = this | 
|     ,success = options.success | 
|     ,error = options.error | 
|     ,request = setter.request | 
|     ,response = setter.response | 
|     ,debug = function(){ | 
|       return setter.debug  | 
|         ? '<br><cite>URL:</cite>' + options.url | 
|       : ''; | 
|     }; | 
|      | 
|     options.data = options.data || {}; | 
|     options.headers = options.headers || {}; | 
|      | 
|     if(request.tokenName){ | 
|       //自动给参数传入默认 token | 
|       options.data[request.tokenName] = request.tokenName in options.data  | 
|         ?  options.data[request.tokenName] | 
|       : (layui.data(setter.tableName)[request.tokenName] || ''); | 
|        | 
|       //自动给 Request Headers 传入 token | 
|       options.headers[request.tokenName] = request.tokenName in options.headers  | 
|         ?  options.headers[request.tokenName] | 
|       : (layui.data(setter.tableName)[request.tokenName] || ''); | 
|     } | 
|      | 
|     delete options.success; | 
|     delete options.error; | 
|   | 
|     return $.ajax($.extend({ | 
|       type: 'get' | 
|       ,dataType: 'json' | 
|       ,success: function(res){ | 
|         var statusCode = response.statusCode; | 
|          | 
|         //只有 response 的 code 一切正常才执行 done | 
|         if(res[response.statusName] == statusCode.ok) { | 
|           typeof options.done === 'function' && options.done(res);  | 
|         }  | 
|          | 
|         //登录状态失效,清除本地 access_token,并强制跳转到登入页 | 
|         else if(res[response.statusName] == statusCode.logout){ | 
|           view.exit(); | 
|         } | 
|          | 
|         //其它异常 | 
|         else { | 
|           var error = [ | 
|             '<cite>Error:</cite> ' + (res[response.msgName] || '返回状态码异常') | 
|             ,debug() | 
|           ].join(''); | 
|           view.error(error); | 
|         } | 
|          | 
|         //只要 http 状态码正常,无论 response 的 code 是否正常都执行 success | 
|         typeof success === 'function' && success(res); | 
|       } | 
|       ,error: function(e, code){ | 
|         var error = [ | 
|           '请求异常,请重试<br><cite>错误信息:</cite>'+ code  | 
|           ,debug() | 
|         ].join(''); | 
|         view.error(error); | 
|          | 
|         typeof error === 'function' && error(res); | 
|       } | 
|     }, options)); | 
|   }; | 
|    | 
|   //弹窗 | 
|   view.popup = function(options){ | 
|     var success = 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 elemClose = $('<i class="layui-icon" close>ဆ</i>'); | 
|         layero.append(elemClose); | 
|         elemClose.on('click', function(){ | 
|           layer.close(index); | 
|         }); | 
|         typeof success === 'function' && success.apply(this, arguments); | 
|       } | 
|     }, options)) | 
|   }; | 
|    | 
|   //异常提示 | 
|   view.error = function(content, options){ | 
|     return view.popup($.extend({ | 
|       content: content | 
|       ,maxWidth: 300 | 
|       //,shade: 0.01 | 
|       ,offset: 't' | 
|       ,anim: 6 | 
|       ,id: 'LAY_adminError' | 
|     }, options)) | 
|   }; | 
|    | 
|    | 
|   //请求模板文件渲染 | 
|   Class.prototype.render = function(views, params){ | 
|     var that = this, router = layui.router(); | 
|     views = setter.views + views + setter.engine; | 
|      | 
|     $('#'+ LAY_BODY).children('.layadmin-loading').remove(); | 
|     view.loading(that.container); //loading | 
|      | 
|     //请求模板 | 
|     $.ajax({ | 
|       url: views | 
|       ,type: 'get' | 
|       ,dataType: 'html' | 
|       ,data: { | 
|         v: layui.cache.version | 
|       } | 
|       ,success: function(html){ | 
|         html = '<div>' + html + '</div>'; | 
|          | 
|         var elemTitle = $(html).find('title') | 
|         ,title = elemTitle.text() || (html.match(/\<title\>([\s\S]*)\<\/title>/)||[])[1]; | 
|          | 
|         var res = { | 
|           title: title | 
|           ,body: html | 
|         }; | 
|          | 
|         elemTitle.remove(); | 
|         that.params = params || {}; //获取参数 | 
|          | 
|         if(that.then){ | 
|           that.then(res); | 
|           delete that.then;  | 
|         } | 
|   | 
|         that.parse(html); | 
|         view.removeLoad(); | 
|          | 
|         if(that.done){ | 
|           that.done(res); | 
|           delete that.done;  | 
|         } | 
|          | 
|       } | 
|       ,error: function(e){ | 
|         view.removeLoad(); | 
|          | 
|         if(that.render.isError){ | 
|           return view.error('请求视图文件异常,状态:'+ e.status); | 
|         }; | 
|          | 
|         if(e.status === 404){ | 
|           that.render('template/tips/404'); | 
|         } else { | 
|           that.render('template/tips/error'); | 
|         } | 
|          | 
|         that.render.isError = true; | 
|       } | 
|     }); | 
|     return that; | 
|   }; | 
|    | 
|   //解析模板 | 
|   Class.prototype.parse = function(html, refresh, callback){ | 
|     var that = this | 
|     ,isScriptTpl = typeof html === 'object' //是否模板元素 | 
|     ,elem = isScriptTpl ? html : $(html) | 
|     ,elemTemp = isScriptTpl ? html : elem.find('*[template]') | 
|     ,fn = function(options){ | 
|       var tpl = laytpl(options.dataElem.html()); | 
|        | 
|       options.dataElem.after(tpl.render($.extend({ | 
|         params: router.params | 
|       }, options.res))); | 
|   | 
|       typeof callback === 'function' && callback(); | 
|        | 
|       try { | 
|         options.done && new Function('d', options.done)(options.res); | 
|       } catch(e){ | 
|         console.error(options.dataElem[0], '\n存在错误回调脚本\n\n', e) | 
|       } | 
|     } | 
|     ,router = layui.router(); | 
|      | 
|     elem.find('title').remove(); | 
|     that.container[refresh ? 'after' : 'html'](elem.children()); | 
|      | 
|     router.params = that.params || {}; | 
|      | 
|     //遍历模板区块 | 
|     for(var i = elemTemp.length; i > 0; i--){ | 
|       (function(){ | 
|         var dataElem = elemTemp.eq(i - 1) | 
|         ,layDone = dataElem.attr('lay-done') || dataElem.attr('lay-then') //获取回调 | 
|         ,url = laytpl(dataElem.attr('lay-url')|| '').render(router) //接口 url | 
|         ,data = laytpl(dataElem.attr('lay-data')|| '').render(router) //接口参数 | 
|         ,headers = laytpl(dataElem.attr('lay-headers')|| '').render(router); //接口请求的头信息 | 
|          | 
|         try { | 
|           data = new Function('return '+ data + ';')(); | 
|         } catch(e) { | 
|           hint.error('lay-data: ' + e.message); | 
|           data = {}; | 
|         }; | 
|          | 
|         try { | 
|           headers = new Function('return '+ headers + ';')(); | 
|         } catch(e) { | 
|           hint.error('lay-headers: ' + e.message); | 
|           headers = headers || {} | 
|         }; | 
|          | 
|         if(url){ | 
|           view.req({ | 
|             type: dataElem.attr('lay-type') || 'get' | 
|             ,url: url | 
|             ,data: data | 
|             ,dataType: 'json' | 
|             ,headers: headers | 
|             ,success: function(res){ | 
|               fn({ | 
|                 dataElem: dataElem | 
|                 ,res: res | 
|                 ,done: layDone | 
|               }); | 
|             } | 
|           }); | 
|         } else { | 
|           fn({ | 
|             dataElem: dataElem | 
|             ,done: layDone | 
|           }); | 
|         } | 
|       }()); | 
|     } | 
|      | 
|     return that; | 
|   }; | 
|    | 
|   //自动渲染数据模板 | 
|   Class.prototype.autoRender = function(id, callback){ | 
|     var that = this; | 
|     $(id || 'body').find('*[template]').each(function(index, item){ | 
|       var othis = $(this); | 
|       that.container = othis; | 
|       that.parse(othis, 'refresh'); | 
|     }); | 
|   }; | 
|    | 
|   //直接渲染字符 | 
|   Class.prototype.send = function(views, data){ | 
|     var tpl = laytpl(views || this.container.html()).render(data || {}); | 
|     this.container.html(tpl); | 
|     return this; | 
|   }; | 
|    | 
|   //局部刷新模板 | 
|   Class.prototype.refresh = function(callback){ | 
|     var that = this | 
|     ,next = that.container.next() | 
|     ,templateid = next.attr('lay-templateid'); | 
|      | 
|     if(that.id != templateid) return that; | 
|      | 
|     that.parse(that.container, 'refresh', function(){ | 
|       that.container.siblings('[lay-templateid="'+ that.id +'"]:last').remove(); | 
|       typeof callback === 'function' && callback(); | 
|     }); | 
|      | 
|     return that; | 
|   }; | 
|    | 
|   //视图请求成功后的回调 | 
|   Class.prototype.then = function(callback){ | 
|     this.then = callback; | 
|     return this; | 
|   }; | 
|    | 
|   //视图渲染完毕后的回调 | 
|   Class.prototype.done = function(callback){ | 
|     this.done = callback; | 
|     return this; | 
|   }; | 
|    | 
|   //对外接口 | 
|   exports('view', view); | 
| }); |