# Visual Studio安裝工具 * *Web Compiler(SCSS -> CSS) 專案有在使用, 需安裝(或是自行安裝scss->css 的complier) 已把檔案加在jira(http://jira.evervictory-it.com:8080/browse/TKCMS-336) * AnkhSVN(非必要) # MVC簡易概要 一開始由Global.asax(後端MVC)當作進入點, 1. 瀏覽器像伺服器發出request 2. IIS接收封包 3. 轉給Route(Global.asax裡面的RegisterRoutes) 4. Route在決定要交給HttpHandler or MVCHandler來處理 ![](https://i.imgur.com/SjQzNHU.png) 專案裡會先由HomeController解析到App.cshtml 然後由於_ViewStart裡面有寫@layout 所以APP.cshtml裡面使用@Renderbody渲染index.cshtml ![](https://i.imgur.com/OddJKLt.png) 可參考: https://dotblogs.com.tw/dog0416/2016/06/09/205427 # FE(前端框架帮助文档) ## 框架设计依据 由于BC(博彩)类的web站点的展示形式,如下图所示,一般为一级导航加二级导航,且都是触发某一导航后,替换某一区域内的html片段,故该框架的核心方法为: ``` js option = { html: "", //html字符串,如某个<script type="text/html" id="tpl">中的内容 json: "", //服务端取数据地址 param: {}, //请求的参数 bd: $("#div"), //通过模板引擎生成好的html放到一个容器中 ... // 其它請直接翻代碼 }; loadModule(option); ``` ![](https://i.imgur.com/ViUStZw.png) ## 框架文件详解 * `template.js` // 模板引擎 全名ARTtemplate,第三方文件 可參考:https://aui.github.io/art-template/zh-cn/docs/ * `framework-init.js` // 框架核心文件 详细:该文件中产生两个对象,一个是 `Loader` 构造函数,`loadModule` 这个全局方法调用的就是这个构造函数,一个是 `G.util` 的静态方法,用于添加一些常用的静态方法,如生成`guid(G.util.guid)`,编译模板 `G.util.compile` * `framework-mapping.js` // 框架配置文件 配置每个模块,如导航切换需要用到的html模板地址和从服务端地址,如下 1. 第一種寫法 ```javascript G.map = { ssc: { rule: ["/Htmls/ssc/rule.html"], betdetail: ["/Htmls/betdetail.html", '/Bet/GetBettingSuccess/'], history: { history: ["/Htmls/history.html", "/Report/GetBetSummary/", format_history('history')], date: ["Htmls/history.html", "/Report/GetBetDateSummary/", format_history('date')], detail: ["Htmls/history.html", "/Report/GetBetDetail/", format_history('detail')] } }, pk10: { ... }, "lottery name": { "module name": ["template URL", "GET API URL", "callback function"] } }; ``` 2. 第二種寫法 ```javascript G.map = { betdetail: { html: { betdetail: "/Htmls/betdetail.html" //html }, json: { betdetail: "/Member/GetMemberBetRecord" // api }, format: { betdetail: format_betdetail //api回來的值, 再做處理(Ex: 可能畫面跟資料排序不同等等) } }, tema: { html: { tema: "/Htmls/playtype/tema.html" }, json: { tema: G.action_odds }, format: { tema: format_tema } } ``` * 设置页面初始需要加载哪个模块 ```javascript G.InitHash = "#!kuaida?pagesize=10"; ``` * 设置模板引擎的辅助函数 ```javascript template.helper("format_time", function(){}); ``` * 设置 `jquery.validate` 插件一些默认配置 ```javascript $.validator.setDefaults({}); ``` * 设置路由的回调函数 ```javascript G.hashFn = { supper: (function () { var nav = $("#nav a"); return function (hash_module) { var module = hash_module.module; G.util.load({ bd: main, module: module, param: hash_module.param || {}, html: hash_module.html, json: hash_module.json, hash: hash_module.hash, refresh: hash_module.refresh }); nav.removeClass("on").filter("[name=" + module + "]").addClass("on"); } })() }; $.each(G.map.ssc, function (module) { G.hashFn[module] = G.hashFn.supper; }); ``` 注意:导航中添加的模块名,需要添加到这里,才会执行模块加载方法。 * `jquery.hashchange.js` 浏览器url hash值变化后,调用hashchange事件,单页面浏览器前进后退时用到,第三方插件,调用已集成到`framework-init.js`中 * `jquery.dialog.js` //弹出框的插件 提供: ` $.alert("text", fn) //提示框 ` ` $.confirm("text", fn) //确认框 ` ` $.dialog(option) //弹出框 ` 弹出框分两种情况: 1. 普通的用法 ``` js $.dialog({ html : "<div>aaa</div>" //html片段 }); ``` 1. 加载服务器模板 ``` js $.dialog({ module: "" //framework-mapping.js 中配置的 G.map[name]中的name值 html: "" //远程模板地址 G.map[name].html[ name2 ] 中 name2的值 json: "" //远程模板地址 G.map[name].json[ name3 ] 中 name3的值 param: {} //需要用到的参数 }); ``` * `jquery.validate.js` //表单验证插件,第三方 ```javascript $("form").validate({ submitHandler: function (form) { _this.doSave(form); } }); ``` 現多以 `initialize.call(this);` 取代。 * `jquery.tooltip.js` //错误冒泡提示 ``` javascript $("input").tooltip({ html: "这是必填字段" //冒泡显示的内容 isFocus: true 是否获取焦点 isSelect: true 是否选中 }); ``` * `module-*.js` 对应模块的业务处理文件 ``` javascript function A (d) { //该形参 d 为一个Html片段中 `<div name="module" id=’a’></div>` 的元素引用 this.d = d; } ``` * module-* 玩法的命名規則通常是以拼音為主 Ex: module-tema(tema為特碼拼音) * `A.prototype.init = function(){}` //模块加载完成后会自动执行 init 方法 * `G.modules[moduleid] = A;` 建立 html 与 js 之间的关联 module id 为 div标签且name="module"的id值 * `module-pager.js` //分页模块 ```html <div name="module" id="pager" class="pager" action="account.account" hash="#!account" format="callback_function_name" param="a=123&b=567"> <select name="pagesize" class="pagesize"> {{pages = [10,20,30,60,100]}} {{each pages as page}} <option value="{{page}}" {{if Data.PageSize == page}}selected{{/if}}>{{page}}</option> {{/each}} </select> 第 <span class="pageindex red">{{Data.PageIndex}}</span> 页 共 <span class="pagecount red">{{Data.PageCount}}</span> 页 共 <span class="recordcount red">{{Data.RecordCount}}</span> 条 <a href="javascript:void(0)" class="fn-first">首页</a> <a href="javascript:void(0)" class="fn-prev">上一页</a> <a href="javascript:void(0)" class="fn-next">下一页</a> <a href="javascript:void(0)" class="fn-last">尾页</a> <input type="text" class="input w30 fn-index"> <input type="button" class="btn w30 fn-go" value="GO" /> </div> ``` 以上为一段分页 html 代码 當一頁有多個pager的話,記得在module.pager.js最下方多輸出 ``` javascript G.modules.pager = Pager G.modules.pager2 = Pager G.modules.pager3 = Pager G.modules.pager4 = Pager ``` `action: //需要请求的服务器地址` `pagebody: //需要将分页处理好的html片段放到哪个容器中,值为容器的id` `template: //需要用到哪个<script type="text/html" id="tpl">中的值作为分页的模板` `param: //分页需要用到的参数,格式 a=1&b=2` ## 完整url解析 当一个导航加上A链接,如 `href=" #!aaa.bbb|ccc?ddd=1 "` 解析成的格式 ``` javascript loadModule({ module: "aaa", html: "bbb", json:"ccc", param: {ddd : 1} }); ``` 當loadModule中有使用到param的話, 對應的html 裡面就可以使用到該資料 例: module-tema.js ```javasript loadModule({ module:"aaa", html: "bbb", json: "ccc", param: {ddd : 1} }) ``` bbb.html ```htmlmixed <div name="module"> <div> // Param要用大寫P // Param.ddd = 1 {{Param.ddd}} </div> </div> ``` `module-tema.js` //特碼的邏輯代码 先定义一个tema的构造函数 ``` javascript function Tema(d) { this.d = $(d); } ``` 一些事件绑定添加到其中,其中扩展方法自由发挥,如 ``` javascript Tema.prototype.init = function () { var _this = this; this.d.on("click", "#selectAll", function () { // do something }); this.d.on("click", ".fn-cancelbet", function () { _this.cancelBet(); }); } Tema.prototype.cancelBet = function () { // do something }; ``` 绑定html与js的关联 ``` js G.module.tema = Tema; * 框架內使用*javascript prototype*的寫法 ![](https://i.imgur.com/bnTBZdV.png) * 共用模塊 有些module-*.js裡面可能包含不同的html, 使用相同的模組 , 甚至不同的html, 不同的模組 舉例(marksix2 > Scripts > module-tema.js) ```javascript ... Tema.prototype.destroy = function () { if (this.id == 'zhengtema') { doc.triggerHandler("showZheng", [false]); } if (this.timer_oddsloop) { clearInterval(this.timer_oddsloop); } }; G.modules.tema = Tema; // 特碼 G.modules.zhengma = Tema; // 正碼 G.modules.zhengtema = Tema; // 正特碼 function QuickBet(d) { this.d = $(d); this.UseLastOdds = false; this.data = [d.json.Param]; } QuickBet.prototype.init = function () { initialize.call(this); this.BetMoney = $("#BetMoney").on("focus", function () { this.value = G.pre_set ? G.pre_money : this.value; }).val(G.pre_set ? G.pre_money : this.value).input_digits(); }; ... QuickBet.prototype.doFailBet = function (message) { var data = {}, param = { "List": this.data }; data.Message = message; $.extend(data, param); doc.triggerHandler("betfailed", [data]); }; G.modules.quickbet = QuickBet; ``` * html、json兩者互相如何傳遞資料? 以六平台為例 ```javascript G.map = { company: { html: { company: "/Htmls/company/company.html", }, json: { company: "/Company/GetCompanyList", } ``` 簡單來說,讀取company.html後會打GetCompanyList的api, 然後會進入到在framwork-init.js裡面的Loader, 其中 ```javascript Loader.prototype.getJSON = function(){ var _this = this; jsonurl = /^\/.+/.test(option.json) ? option.json : option.json ? G.map[option.module].json[option.json] : option.module && !option.html ? G.map[option.module].json[option.module] : null; if (!jsonurl) { this.flag += 1; this.flashHTML(option); return; } G.get({ url: jsonurl, data: option.param, success: function (json) { _this.flag += 1; _this.jsondata = json; **會把值塞到jsondata裡面** if (option.jsonSuccess) { _this.jsondata = option.jsonSuccess(json) || json; } else { if (!option.html && !option.json) { _this.jsondata = G.map[option.module].format && G.map[option.module].format[option.module] ? G.map[option.module].format[option.module](json) || json : json; } else if (option.module && option.json) { _this.jsondata = G.map[option.module].format && G.map[option.module].format[option.json] ? G.map[option.module].format[option.json](json) || json : json; } } if(!option.hash || option.hash == G.util.getHash()){ _this.flashHTML(option); } }, } ``` 最後在Loader.prototype.flashHTML裡的 ```javascript this.jsondata.LoginAccount = LOGIN_ACCOUNT; **其他要共用的東西可參照此寫法 strHTML = G.util.compile(this.template, this.jsondata); ``` 再把jsondata跟template compile ,html就會拿到資料 * HTML標籤內驗證 ```html= <input type="text" class="w60 ime-dis" id="pre_money" lessthan="100"> ``` lessthan 是設定值小於100,相關設定在framework-mapping.js內 ```javascript $.validator.addMethod("lessthan", function (value, element, param) { var val = $.trim($(param).val()); val = val ? parseFloat(val) : null; value = parseFloat(value); return this.optional(element) || !val || value <= val; }, "搜索的最小值不能超过最大值!"); ``` 其他驗證有positive(正數)positivedigits(正整數)nonnegative(非負數)...等