define(function(require, exports, module){ var mp = require('mp'); var Node = mp.Class.extend({ $elem:null, $event:null, nodeName:'div', ctor:function(data){ if(!data){data = {}} this.nodeName = data.nodeName || 'div'; this.$elem = this.$elem || data.$elem; if(!this.$elem){ this.isNew = true; this.$elem = $(document.createElement(this.nodeName)); } this.className = data.className; if(this.className){ this.$elem.addClass(this.className); } //其他属性 this.attribute = data.attribute || {}; //属性 for(var p in this.attribute){ this.$elem.attr(p,this.attribute[p]); } }, addChild:function(child){ this.$elem.append(child.$elem); child.parent = this; }, removeChild:function(child){ child.parent = null; child.$elem.remove(); } }) module.exports = Node; })
define(function(require, exports, module){ var $ = require('$'), mp = require('mp'); var Router = mp.Class.extend({ history:[], historyIndex:0, ctor:function(app){ this.$app = app; }, init:function(){ var self = this; window.addEventListener('hashchange',function(e){ var newHash = location.hash.substring(1); self.loadUrl(newHash); }); //first time load var newHash = location.hash.substring(1); self.loadUrl(newHash); }, loadUrl:function(url,option,cacheHtml,effect){ //数据校验 if(!url){ this.loadUrl(this.$app.config.root,option,cacheHtml,effect); return; } //配置 if(!option){ option = {}; } if(cacheHtml){ option.cacheHtml = cacheHtml; } if(effect){ option.effect = effect; } var obj = this.parse.call(this,url,option),view; //当前view修改参数,不重新渲染,执行view的reload方法 //_ 记录了当前view的id if(this.$app.view && this.$app.view._ === obj.view){ view = this.$app.view; view.params = obj.params; view.reload(); } //否则重新构建view else{ var self = this; require.async(obj.view,function(View){ if(View){ view = new View({app:self.$app}); view._ = obj.view; view.params = obj.params; self.$app.loadView(view); } self.push(url,option,view); }); } }, backView:function(record){ var record = this.pop(); if(record){ this.loadUrl.apply(this,record); } }, parse:function(url, option){ var atag,pathname,search,params = {},view,arr,pair,filename; atag = document.createElement('a'); atag.href = url; pathname = atag.pathname; search = atag.search.substr(1); if(pathname == '/'){ pathname = this.$app.config.root || '/index'; } //文件名和最后一个文件夹相同 filename = pathname.split('/').slice(-1); view = this.$app.config.viewfolder + pathname + '/' + filename; for(var p in option){ params[p] = option[p]; } arr = search.split('&') arr.forEach(function(item){ pair = item.split('=') if(pair[0]){ params[pair[0]] = pair[1] } }); return { pathname:pathname, view:view, params:params, template:pathname.substr(1) }; }, push:function(){}, pop:function(){}, startup:function(){} }); Router.create = function(app){ return new Router(app); } module.exports = Router; })
define(function(require, exports, module){ var $ = require('$'), mp = require('mp'); var Router = mp.Class.extend({ history:[], historyIndex:0, ctor:function(app){ this.$app = app; }, init:function(){ var self = this; window.addEventListener('popstate',function(e){ if(e.state){ if(e.state.url){ if(e.state.historyIndex && e.state.historyIndex < self.historyIndex){ //控制app跳转 self.backView(); } else{ e.state.option.browser = true; //控制app跳转 self.loadUrl(e.state.url,e.state.option); } } } }); }, loadUrl:function(url,option,cacheHtml,effect){ //数据校验 if(!url){ this.loadUrl(this.$app.config.root,option,cacheHtml,effect); return; } //配置 if(!option){ option = {}; } if(cacheHtml){ option.cacheHtml = cacheHtml; } if(effect){ option.effect = effect; } var obj = this.parse.call(this,url,option),view; //当前view修改参数,不重新渲染,执行view的reload方法 //_ 记录了当前view的id if(this.$app.view && this.$app.view._ === obj.view){ view = this.$app.view; view.params = obj.params; view.reload(); } //否则重新构建view else{ var self = this; require.async(obj.view,function(View){ if(View){ view = new View({app:self.$app}); view._ = obj.view; view.params = obj.params; self.$app.loadView(view); } self.push(url,option,view); }); } }, backView:function(record){ var record = this.pop(); if(record){ this.loadUrl.apply(this,record); } }, parse:function(url, option){ var atag,pathname,search,params = {},view,arr,pair,filename; atag = document.createElement('a'); atag.href = url; pathname = atag.pathname; search = atag.search.substr(1); if(pathname == '/'){ pathname = this.$app.config.root || '/index'; } //文件名和最后一个文件夹相同 filename = pathname.split('/').slice(-1); view = this.$app.config.viewfolder + pathname + '/' + filename; for(var p in option){ params[p] = option[p]; } arr = search.split('&') arr.forEach(function(item){ pair = item.split('=') if(pair[0]){ params[pair[0]] = pair[1]; } }); return { pathname:pathname, view:view, params:params, template:pathname.substr(1) }; }, push:function(url,option,view){ this.history.push([url,option,view.$elem.html()]); if(this.history.length > 10){ this.history = this.history.slice(5); } this.historyIndex++; if(!option.browser){ history.pushState({url:url,option:option,historyIndex:self.historyIndex},view.title,url); } }, pop:function(){ this.history.pop(); var record = this.history.pop() || ['','','']; record.push('right'); return record; }, startup:function(){ this.loadUrl(window.location.href); } }); Router.create = function(app){ return new Router(app); } module.exports = Router; })
define(function (require, exports, module) { var mp = require('mp'), $ = require('$'); var objectToParams = function (obj, decodeUri) { var param = $.param(obj); if (decodeUri) { param = decodeURIComponent(param); } return param; }; var console = window.console; /** * 网络请求 * @class net * @static */ var Net = mp.Class.extend({ ctor:function(app){ this.$app = app; }, _progressBar:[], /** * 发起请求 * @method send * @param {Object} cgiConfig 配置 * @param {Object} opt 选参 */ send: function (cgiConfig, opt) { var _self = this, _cgiConfig = cgiConfig, _data = opt.data || {}, _url = "", _cb = null; if (!_cgiConfig) { _cgiConfig = { url: opt.url, method: opt.method }; } if (_cgiConfig) { // 成功回调 _cb = function (ret) { opt.cb && opt.cb(ret); }; var urlParams = { t: new Date().getTime() }; _url = this._addParam(_cgiConfig.url, urlParams); if (_cgiConfig.method && _cgiConfig.method.toLowerCase() === "post") { return this.post(_url, _data, _cb); } else { return this.get(_url, _data, _cb); } } }, /** * GET请求 * @method get * @param {String} url URL * @param {Object} data 参数 * @param {Function} cb 回调函数 */ get: function (url, data, cb) { return this._ajax(url, data, 'GET', cb); }, /** * POST请求 * @method post * @param {String} url URL * @param {Object} data 参数 * @param {Function} cb 回调函数 */ post: function (url, data, cb) { return this._ajax(url, data, 'POST', cb); }, request:function(options){ var self = this; var request = options.request, data = options.data, success = options.success, error = options.error, button = options.button, eventName = null; //恢复按钮 if(button){ var $button = $(button); eventName = $button.addClass('disabled').data('event'); $button[0].removeAttribute('data-click-event'); } var cb = function(ret,info){ if($button){ $button.removeClass('disabled')[0].setAttribute('data-click-event', eventName); } var _code = ret.code; var breakdefault = false; if(self.$app.config.netback){ breakdefault = self.$app.config.netback.call(self.$app,options,ret,info); } if(!breakdefault){ if (_code === 0) { if(success){ success(ret.data,info); } } else { if(error){ error(ret.msg,_code,ret.data,info); } } } } if(request.fakecallback){ request.fakecallback(data, cb); } else{ this[request.method](request.url, data, cb); } }, _ajax: function (url, data, method, cb) { var self =this; var returnVal = null; var progressBar = null; if(this.$app.config.xhrProgress){ progressBar = self._showProgress(); } var starttime = +new Date(); this.isBusy = true; (function(pbar){ returnVal = $.ajax({ type: method, url: url, data: data, success: function (data) { self.isBusy = false; self._hideProgress(pbar); cb(data, {starttime:starttime}); }, error: function (jqXHR) { self.isBusy = false; self._hideProgress(pbar); var data = {}; try{ data = JSON.parse(jqXHR.responseText); } catch(e){ console.error('jqXHR.responseText parse error'); data.code = jqXHR.status; data.msg = jqXHR.statusText; data.data = {}; } cb(data, {starttime:starttime}); } }); if(pbar){ returnVal.onprogress = function(evt){ var progressWidth = ((evt.loaded / (evt.total || (evt.loaded>1000?evt.loaded:1000))) * pbar.clientWidth*0.99) | 0; }; } })(progressBar); return returnVal; }, _showProgress: function(){ var progressBar = document.createElement('div'); progressBar.setAttribute('style', 'position:fixed;height:3px;top:0;background:green;'+ 'transition:all .6s ease;width:0;z-index:100'); document.body.appendChild(progressBar); progressBar.style.width = document.body.clientWidth+'px'; return progressBar; }, _hideProgress: function(elem){ if(elem){ document.body.removeChild(elem); } }, _addParam: function (url, p) { var s = /\?/.test(url) ? '&' : '?'; url += s + objectToParams(p); return url; } }); Net.create = function(mpNode){ return new Net(mpNode); }; module.exports = Net; });