日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

我的MVVM框架 v0.1发布

發布時間:2025/3/17 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 我的MVVM框架 v0.1发布 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

如果經常瀏覽我博客的人就發現,我三個月前就搞鼓過一下什么MVVM與MVC的比較,knockout.js與ember.js。然后就沒動靜了,因為之后一個月,我的MVVM就孵化出來,開發代碼很逆天也很齷鹺,就叫avalon(WPF開發代號)。我覺得,都是好東西,相互借鑒是沒所謂,只要造福IT民工!

說說MVVM的重要性,它雖然是從MVC中衍生出來的,但其雙向綁定機制是特有的,完全是面向界面開發而生,這是傳統的MVC比不了。最近我拉了一伙人在搞我的mass UI就遇到這問題了。

//由mass UI開發團隊的Hodor 提供 define('panel',['$node','$event','$css','$flow','./ejs' ], function(){$.ui = $.ui||{}var defaults = {showHead : true,showFoot : true,closeAble : true,parent : 'body',content : {title : 'title',body : 'body',foot : ''},css : {width : 400,height : 200}};$.ui.Panel = $.factory({inherit: $.Flow,init: function(opts) {this.setOptions ("data", defaults, opts )var self = this;self.template = $.ejs.compile('<div class="panel_wrap">\<% if( data.showHead ){ %>\<div class="panel_header">\<div class="panel_title">\<%= data.content.title %>\</div>\<% if( data.closeAble ){ %>\<span class="panel_closer"></span>\<% } %>\</div>\<% } %>\<div class="panel_body">\<%= data.content.body %>\</div>\<% if( data.showFoot ){ %>\<div class="panel_foot">\<%= data.content.foot %>\</div>\<% } %>\</div>');self.show();},show : function() {this.fire ( 'beforeshow' )this.ui && this.ui.remove();this.ui = $(this.template( this.data )).appendTo( this.parent ).css ( this.css ).show ();this.fire ( 'show' )},hide : function() {this.ui && this.ui.hide().remove();this.ui = undefined;this.fire ( 'hide' );},set : function( keyChain, val ) {//每改一個屬性就重刷整個視圖,因此不能容納子控件,除非我們多做一些額外工作var keys = keyChain.split('.');var key;var ret = this;while( keys.length > 1){key = keys.shift();ret[key] = ret[key] != undefined ? ret[key] :{};ret = ret[key];}ret[keys.shift()] = val;this.show();return this;}}); })

遇到的問題與其他UI團隊一樣,其實你看一下jquery UI就知了。一個控件,它肯定有視圖層,這里我們是用ejs v10來生成。生成HTML插入到DOM算是完成了一半,但當我們要修改這個控件的一些屬性,一些與視圖相關的屬性就遇到麻煩了。比如說title屬性,如果是jquery ui,它肯定先到這個控件的ID,然后再找包含這個title的元素節點,再替換掉它的文本。用jquery是這樣寫出:

setTilte: function(newTitle){$(this.UIid).find("jquery-panel-title").text(newTitle);//更新視圖this.title = newTitle;//同時同步對應的屬性}getTitle: function(){return this.title;}

如果一個控件涉及的視圖屬性越多,控件這樣的訪問器就越多!長此以往不是辦法!像日歷組件,你可以看到它是多么臃腫。

這時該到MVVM出馬了。它把這些與視圖顯示相關的屬性全部收集到一起,包括基于這些屬性的屬性,比如說fullName是基于lastName與firstName,它是通過函數生成的,這個在模型(M)里是不存在的,但它存于視圖模型(VM)中。由于雙向綁定的存在,我們修改了VM的一個值,它立即自動刷新視圖中對應的位置的值,這過程完全不需要動用到選擇器!

基于選擇器的方式是最不可靠的,因為視圖的變更最頻繁,某一天PM說要多加一功能或不要一功能,于是就多幾個父節點或少幾個子節點,把HTML的層級關系搞得亂七八糟,我們的選擇器尋找就得重寫一次!

因此對于這些DOM操作,我們最好也封裝一層,這是比jquery的DOM操作函數更高層的封裝,目的是讓控件開發者遠離視圖層,他們只需要關注于模型層。如果我們把DOM操作看成增刪改查,那么原始的DOM API相當于直接用二進制手段暴力去改數據庫,而像jQuery等主流庫提供了強大的選擇器引擎與DOM操作函數,相當于發明SQL,而像knockout.js這樣的MVVM框架擁有尖端的依賴鏈機制、雙向綁定,讓智能的集化操作,事務與鎖成為可能,是DOM級別的“ORM系統”!

順便一提,在VM中,所有屬性都是函數,每個函數都是讀寫結合,像jquery的html, attr, text那樣便捷!這有出于兼容IE678的考量,因為它們不支持Object.defineProperty這樣的屬性描述符(或支持不良好,如IE8)。

我的MVVM v1完全是向knockout.js致敬的,用法與它的一模一樣,不過代碼量少了許多。具體教程與實可以看以下鏈接:

  • MVVM模式的實踐——avalon模塊
  • avalon模塊:依賴鏈
  • avalon模塊的內建適配器

最近看了許多MVVM的實現,功力大增,估計v2秒換胎脫骨,更精簡更高效,敬請期待!

define("avalon",["data","attr","event","fx"], function(){/* JS UI Component 最終還是通過 HTML 來描述界面,當 js object 的數據發生變化或者執行某個動作時,需要通知到對應的html,使其發生相應變化。于是js object 需要得到他在頁面上對應的html的句柄,通常做法,是在創建html的時候將createElement返回的句柄保存在js object 內部的某個變量中,或者賦值給html eLement一個唯一的ID,js object 根據這個ID來找到對應的HTML Element。同樣,當htm elementl的事件(例如onclick)要通知到相對應的 js object 或者回調js object的某個方法或屬性時,也需要得到該js object的一個引用。我的意思是建立一種統一的規則,js object和他相對應的 html 能通過這種規則互相訪問到對方。 建立這個關聯以后,實現js object和對應 html 的數據邦定和數據同步等問題就簡單多了*/var disposeObject = {}var cur, ID = 1;var registry = {}var dependent = {}var fieldFns = {ensure : function(d){if(this.list.indexOf(d) == -1){this.list.push(d);}},lock : function(){this.locked = true;},unlock : function(){delete this.locked;},notify : function(){//通知依賴于field的上層$.computed更新var list = this.list || [] ;if( list.length ){var safelist = list.concat(), dispose = falsefor(var i = 0, el; el = safelist[i++];){delete el.cache;//清除緩存if(el.locked === true)breakif(el.dispose === true || el() == disposeObject ){//通知頂層的computed更新自身el.dispose = dispose = true}}if( dispose == true ){//移除無意義的綁定for ( i = list.length; el = list[ --i ]; ) {if( el.dispose == true ){el.splice( i, 1 );}}}}}}$.avalon = {//為一個Binding Target(節點)綁定Binding Source(viewModel)setBindings: function( source, node ){node = node || document.body; //確保是綁定在元素節點上,沒有指定默認是綁在body上//開始在其自身與孩子中綁定return setBindingsToElementAndChildren( node, source, true );},//取得節點的數據隱藏hasBindings: function( node ){var str = node.getAttribute( "data-bind" );return typeof str === "string" && str.indexOf(":") > 1},//將字符串變成一個函數evalBindings: function(expression, level){var body = "return (" + expression + ")";for (var i = 0; i < level; i++) {body = "with(sc[" + i + "]) { " + body + " } ";}return Function( "sc", body );},//轉換數據隱藏為一個函數parseBindings : function( node, context ){var jsonstr = $.normalizeJSON( node.getAttribute("data-bind"), true, context );var fn = $.avalon.evalBindings( jsonstr, 2 );//限制為兩層,減少作用鏈的長度return fn;},//開始收集依賴detectBegin: function( field ){var uuid = $.avalon.register( field )if( cur ){cur[uuid] = field}//用于收集依賴var prev = cur;cur = dependent[uuid];cur.prev = prev},//添加依賴到鏈中detectAdd: function( field ){if(cur){var uuid = $.avalon.register( field )cur[ uuid ] = field;}},//結束依賴收集detectEnd: function( field ){var deps = dependent[ field.observableID ] || {};cur = deps.prev;for(var key in deps){if(deps.hasOwnProperty(key) && (key != "prev")){var low = registry[ key ];low.ensure(field)}}},//注冊依賴register: function( field ){var uuid = field.observableIDif(!uuid || !registry[uuid] ){field.observableID = uuid = "observable" +(++ID);registry[uuid] = field;//供發布者使用dependent[uuid] = {};//收集依賴field.list = []$.mix(field, fieldFns);}return uuid;}}$.observable = function( val ){var cur = val;function field( neo ){$.avalon.detectAdd(field)if( arguments.length ){//setterif(cur !== neo || Array.isArray(cur) ){cur = neo;field.notify()}}else{//getterreturn cur;}}field.toString = field.valueOf = function(){return cur;}field();return field;}$.computed = function( obj, scope ){var getter, setter, cur//構建一個至少擁有getter,scope屬性的對象if(typeof obj == "function"){//getter必然存在getter = obj}else if( typeof obj == "object" && obj ){getter = obj.gettersetter = obj.setter;scope = obj.scope;}function field( neo ){if( arguments.length ){if(typeof setter === "function"){field.lock()//setter會喚起其依賴的$.observable與$.computed重新計算自身,但它們也會觸發其上級更新自身//由于自身已經先行更新了,沒有再計算一次neo = setter.apply( scope, arguments );field.unlock()}}else{if( "cache" in field ){//getterneo = field.cache;//從緩存中讀取,防止遞歸讀取}else{neo = getter.call( scope );field.cache = neo;//保存到緩存}}if(cur !== neo || Array.isArray(cur) && (JSON.stringify(cur) != JSON.stringify(neo)) ){cur = neofield.notify()}return cur;}field.toString = field.valueOf = function(){return cur;}$.avalon.detectBegin( field )field();$.avalon.detectEnd( field )return field;}$.observableArray = function(array){if(!arguments.length){array = []}else if(!Array.isArray){throw "$.observableArray arguments must be a array"}var field = $.observable(array);makeObservableArray(field);return field;}function makeObservableArray( field ){("pop,push,shift,unshift,slice,splice,sort,reverse,remove,removeAt").replace( $.rword, function( method ){field[method] = function(){var array = this(), n = array.lengthArray.prototype.unshift.call(arguments, array);$.Array[method].apply( $.Array, arguments );if( /sort|reverse|splice/.test(method) ){field.notify()}else if( array.length != n ){field.notify()}}});}//template - name//foreach - data//value - data//options - data//event - handler//MVVM三大入口函數之一$.applyBindings = $.setBindings = $.avalon.setBindings;var parseBindings = $.avalon.parseBindings;//dataFor與contextFor是為事件的無侵入綁定服務的$.contextFor = function(node) {switch (node.nodeType) {case 1:var context = $._data(node,"bindings-context");if (context) return context;if (node.parentNode) return $.contextFor(node.parentNode);break;case 9:return void 0}return void 0;};$.dataFor = function(node) {var context = $.contextFor(node);return context ? context['$data'] : void 0;};//在元素及其后代中將數據隱藏與viewModel關聯在一起function setBindingsToElementAndChildren( node, source, setData ){if ( node.nodeType === 1 ){var continueBindings = true;if( $.avalon.hasBindings( node ) ){continueBindings = setBindingsToElement(node, source, setData ) }if( continueBindings ){var elems = getChildren( node )elems.length && setBindingsToChildren( elems, source, setData )}}}//viewModel類$.viewModel = function(current, parent){$.mix( this,current );if ( parent) {$.mix( this, parent );this['$parentContext'] = parent;this['$parent'] = parent['$data'];this['$parents'] = (parent['$parents'] || []).slice(0);this['$parents'].unshift( this['$parent'] );} else {this['$parents'] = [];this['$root'] = current;}this['$data'] = current;}$.viewModel.prototype = {extend : function(source){return $.mix( this,source )},alias: function( neo, old){if(this[ neo ]){this[ this[neo] ] = this[old]}return this;}}//為當前元素把數據隱藏與視圖模塊綁定在一塊function setBindingsToElement( node, context, setData ){//如果bindings不存在,則通過getBindings獲取,getBindings會調用parseBindingsString,變成對象var callback = parseBindings( node, context )//保存到閉包中context = context instanceof $.viewModel ? context : new $.viewModel( context );if( setData ){$._data(node,"bindings-context",context)}var getBindings = function(){//用于取得數據隱藏try{return callback( [ node, context ] )}catch(e){$.log(e)}}var bindings = getBindings();var continueBindings = true;for(var key in bindings){var adapter = $.bindingAdapter[key];if( adapter ){if( adapter.stopBindings ){continueBindings = false;}associateDataAndUI( node, bindings[key], context, key, getBindings)}}return continueBindings;}//setBindingsToChildren的第三第四參數是為了實現事件的無侵入綁定function setBindingsToChildren(elems, context, setData, force){for(var i = 0, n = elems.length; i < n ; i++){var node = elems[i]setBindingsToElementAndChildren( node, context, setData && !force );if( setData && force ){//這是由foreach綁定觸發$._data(node,"bindings-context", context)}}}//有一些域的依賴在定義vireModel時已經確認了//而對元素的操作的$.computed則要在bindings中執行它們才知function associateDataAndUI(node, field, context, key, getBindings){var adapter = $.bindingAdapter[key], initPhase = 0, cur;function symptom(){//這是依賴鏈的末梢,通過process操作節點if(!node){return disposeObject;//解除綁定}if(typeof field !== "function"){var bindings = getBindings();//每次都取一次,因為viewModel的數據已經發生改變field = bindings["@mass_fields"][key];}if(initPhase === 0){cur = field();adapter.init && adapter.init(node, cur, field, context, symptom);}var neo = field();if( key == "case"){//這個應該如何處理更好呢?if(field === context.$switch){//$default;neo = !context.$switch.not;}else{//如果前面有一個通過,那么它將不會進入$default分支;neo = context.$switch() == neo;if( neo ){context.$switch.not = true;}}}if(initPhase === 0 || cur != neo || Array.isArray(cur) ){//只要是處理bool假值的比較cur = neo;adapter.update && adapter.update(node, cur, field, context, symptom);}initPhase = 1;}$.computed( symptom, context.$data );}var inputOne = $.oneObject("text,password,textarea,tel,url,search,number,month,email,datetime,week,datetime-local")//一個數據綁定,負責界面的展示,另一個是事件綁定,負責更高層次的交互,比如動畫,數據請求,//從現影響viewModel,導致界面的再渲染$.bindingAdapter = {text: {update: function( node, val ){val = val == null ? "" : val+""if(node.childNodes.length === 1 && node.firstChild.nodeType == 3){node.firstChild.data = val;}else{$( node ).text( val );}}},value:{init: function(node, val, field){node.value = val;if(/input|textarea/i.test(node.nodeName) && inputOne[node.type]){$(node).on("input",function(){field(node.value)});}}},html: {update: function( node, val ){$( node ).html( val )},stopBindings: true},visible: {update: function( node, val ){node.style.display = val ? "" : "none";}},enable: {update: function( node, val ){if (val && node.disabled)node.removeAttribute("disabled");else if ((!val) && (!node.disabled))node.disabled = true;}},"class": {update: function( node, val ){if (typeof val == "object") {for (var className in val) {var shouldHaveClass = val[className];toggleClass(node, className, shouldHaveClass);}} else {val = String(val || '');toggleClass(node, val, true);}}} ,// { text-decoration: someValue }// { color: currentProfit() < 0 ? 'red' : 'black' }style: {update: function( node, val ){var style = node.style, styleNamefor (var name in val) {styleName = $.cssName(name, style) || namestyle[styleName] = val[ name ] || "";}}},attr: {update: function( node, val ){for (var name in val) {$.attr(node, name, val[ name ] )}}},click: {init: function( node, val, field, context ){$(node).bind("click",function(e){field.call( context, e )});}},"switch":{init:function( node, val, field, context){context.$switch = field;context.$default = fieldsetBindingsToChildren( node.childNodes, context )},update:function(node, val, field, context){delete context.$switch.not;//每次都清空它},stopBindings: true},checked: {init: function( node, val, field, context ){if(context.$hoist && context.$hoist.nodeType == 1 ){var expr = node.tagName +"['data-bind'="+node.getAttribute("data-bind") +"]";context.$hoisting && $(context.$hoist).delegate( expr,"change", function(){field(node.checked);});}else{$(node).bind("change",function(){field(node.checked);});}},update:function(node, val ){if ( node.type == "checkbox" ) {if (Array.isArray( val )) {node.checked = val.indexOf(node.value) >= 0;} else {node.checked = val;}} else if (node.type == "radio") {node.checked = ( node.value == val );}}}}//if unless with foreach四種bindings都是使用template bindings"if,unless,with,foreach,case".replace($.rword, function( type ){$.bindingAdapter[ type ] = {update : function(node, val, field, context, symptom){if(type == "case" && (typeof context.$switch != "function" )){throw "Must define switch statement above all";}$.bindingAdapter['template']['update'](node, val, function(){switch(type){//返回結果可能為 -1 0 1 2case "case":case "if":return !!val - 0;//1case "unless":return !val - 0;//0case "with":return 2;//2default:return -1;}}, context, symptom);},stopBindings: true}});var Tmpl = function(t){this.template = tthis.nodes = $.slice(t.childNodes)}Tmpl.prototype.recovery = function(){this.nodes.forEach(function( el ){this.template.appendChild(el)},this);return this.template}$.bindingAdapter[ "template" ] = {update: function(node, data, field, context, symptom){var ganso = symptom.ganso//取得最初的那個節點的內部作為模塊if( !symptom.ganso ){//緩存,省得每次都創建//合并文本節點數node.normalize();//保存模板ganso = node.ownerDocument.createDocumentFragment();while((el = node.firstChild)){ganso.appendChild(el)}symptom.ganso = ganso;//復制一份出來放回原位var first = ganso.cloneNode(true);symptom.references = [ new Tmpl( first ) ];//先取得nodes的引用再插入DOM樹node.appendChild( first );symptom.prevData = [{}];//這是偽數據,目的讓其update}// console.log("===============")var code = field(), el;first = symptom.references[0];// console.log(code)if( code > 0 ){ //處理with if bindingstemplate = first.recovery();var elems = getChildren( template );node.appendChild( template ); //顯示出來if( elems.length ){if( code == 2 ){//處理with bindingscontext = new $.viewModel( data, context )}return setBindingsToChildren( elems, context, true )}}else if( code == 0){//處理unless bindingsfirst.recovery();}if( code < 0 && data && isFinite(data.length) ){//處理foreach bindingsvar scripts = getEditScripts( symptom.prevData, data, true ), hasDelete//obj必須有x,yfor(var i = 0, n = scripts.length; i < n ; i++){var obj = scripts[i], tmpl = false;switch(obj.action){case "update":tmpl = symptom.references[ obj.x ];//這里要增強break;case "add":tmpl = new Tmpl( ganso.cloneNode(true) );symptom.references.push( tmpl );break;case "retain"://如果發生刪除操作,那么位于刪除元素之后的元素的索引值會發生改變//則重置它們if(obj.x !== obj.y){tmpl = symptom.references[ obj.x ];tmpl.index(obj.y);tmpl = null;}break;case "delete":tmpl = symptom.references[ obj.y ];$(tmpl.nodes).remove();hasDelete = tmpl.destroy = true;tmpl = null;break;};if(tmpl){(function( k, tmpl ){var template = tmpl.templateif(!template.childNodes.length){tmpl.recovery();//update}tmpl.index = $.observable(k)var subclass = new $.viewModel( data[ k ], context);subclass.extend( {$index: tmpl.index// $item: data[ k ]} )// .alias("$itemName", "$data")// .alias("$indexName", "$index");elems = getChildren( template );node.appendChild( template );if(elems.length){setBindingsToChildren(elems, subclass, true, true );}})(obj.y || 0, tmpl);}}symptom.prevData = data.concat();if(hasDelete){symptom.references = symptom.references.filter(function(el){return !el.destroy})};}return void 0},stopBindings: true}$.bindingAdapter.disable = {update: function( node, val ){$.bindingAdapter.enable.update(node, !val);}}var getChildren = function(node){var elems = [] ,ri = 0;for (node = node.firstChild; node; node = node.nextSibling){if (node.nodeType === 1){elems[ri++] = node;}}return elems;}$.bindingAdapter["css"] = $.bindingAdapter["class"]var toggleClass = function (node, className, shouldHaveClass) {var classes = (node.className || "").split(/\s+/);var hasClass = classes.indexOf( className) >= 0;//原className是否有這東西if (shouldHaveClass && !hasClass) {node.className += (classes[0] ? " " : "") + className;} else if (hasClass && !shouldHaveClass) {var newClassName = "";for (var i = 0; i < classes.length; i++)if (classes[i] != className)newClassName += classes[i] + " ";node.className = newClassName.trim();}}var getEditScripts = (function () {// 一個簡單的Levenshtein distance算法//編輯距離就是用來計算從原串(s)轉換到目標串(t)所需要的最少的插入,刪除和替換的數目,//在NLP中應用比較廣泛,如一些評測方法中就用到了(wer,mWer等),同時也常用來計算你對原文本所作的改動數。//http://www.cnblogs.com/pandora/archive/2009/12/20/levenshtein_distance.html//https://gist.github.com/982927//http://www.blogjava.net/phyeas/archive/2009/01/10/250807.html//通過levenshtein distance算法返回一個矩陣,matrix[y][x]為最短的編輯長度var getEditDistance = function(from, to, table){var matrix = [], fn = from.length, tn = to.length;// 初始化一個矩陣,行數為b,列數為avar i, j, td;for(i = 0; i <= tn; i++){matrix[i] = [i];//設置第一列的值table && table.insertRow(i)}for(j = 0; j <= fn; j++){matrix[0][j] = j;//設置第一行的值if(table){for(i = 0; i <= tn; i++){td = table.rows[i].insertCell(j);if(isFinite(matrix[i][j])){td.innerHTML = matrix[i][j];td.className = "zero";}}}}// 填空矩陣for(i = 1; i <= tn; i++){for(j = 1; j <= fn; j++){if( to[i-1] == from[j-1] ){matrix[i][j] = matrix[i-1][j-1];//保留} else {matrix[i][j] = Math.min(matrix[i-1][j-1] + 1, //更新matrix[i][j-1] + 1, // 插入matrix[i-1][j] + 1); //刪除}if(table){td = table.rows[i].cells[j];td.innerHTML = matrix[i][j];}}}$.log(matrix.join("\n"));return matrix;};//返回具體的編輯步驟var _getEditScripts = function(from, to, matrix, table){var x = from.length, y = to.length, scripts = [], _action;if(x == 0 || y == 0){//如果原數組為0,那么新數組的都是新增的,如果新數組為0,那么我們要刪除所有舊數組的元素var n = Math.max(x,y), action = x == 0 ? "add" : "delete";for( var i = 0; i < n; i++ ){scripts[scripts.length] = {action: action,x: i,y: i}}}else{while( 1 ){var cur = matrix[y][x];if( y == 0 && x == 0){break;}var left = matrix[y][x-1]var diagon = matrix[y-1][x-1];var top = matrix[y-1][x];action = "retain"//top == left && cur == diagonvar min = Math.min(top, diagon, left);var td = table && (table.rows[y].cells[x]);x--;y--;if( min < cur ){switch(min){case top:action = "add";x++;break;case left:action = "delete";y++;break;case diagon:action = "update";if(_action){action = _action;_action = false;}break;}} else{switch(min){case top:_action = "add";x++;break;case left:_action = "delete";y++;break;}}if(table){td.className = action;}scripts[scripts.length] = {action:action,x:x,y:y}}}scripts.reverse();return scripts}return function( old, neo, debug ){if(debug){debug = document.createElement("table");document.body.appendChild(debug);debug.className = "compare";}var matrix = getEditDistance( old, neo, debug );return _getEditScripts( old, neo, matrix, debug );}})();//normalizeJSON及其輔助方法與變量void function(){var restoreCapturedTokensRegex = /\@mass_token_(\d+)\@/g;function restoreTokens(string, tokens) {var prevValue = null;while (string != prevValue) { // Keep restoring tokens until it no longer makes a difference (they may be nested)prevValue = string;string = string.replace(restoreCapturedTokensRegex, function (match, tokenIndex) {return tokens[tokenIndex];});}return string;}//https://github.com/SteveSanderson/knockout/wiki/Asynchronous-Dependent-Observables 偉大的東西//https://github.com/rniemeyer/knockout-kendo 一個UI庫//https://github.com/mbest/js-object-literal-parse/blob/master/js-object-literal-parse.jsfunction parseObjectLiteral(objectLiteralString) {var str = objectLiteralString.trim();if (str.length < 3)return [];if (str.charAt(0) === "{")// 去掉最開始{與最后的}str = str.substring(1, str.length - 1);// 首先用占位符把字段中的字符串與正則處理掉var tokens = [];var tokenStart = null, tokenEndChar;for (var position = 0; position < str.length; position++) {var c = str.charAt(position);//IE6字符串不支持[],開始一個個字符分析if (tokenStart === null) {switch (c) {case '"':case "'":case "/":tokenStart = position;//索引tokenEndChar = c;//值break;}//如果再次找到一個與tokenEndChar相同的字符,并且此字符前面不是轉義符} else if ((c == tokenEndChar) && (str.charAt(position - 1) !== "\\")) {var token = str.substring(tokenStart, position + 1);tokens.push(token);var replacement = "@mass_token_" + (tokens.length - 1) + "@";//對應的占位符str = str.substring(0, tokenStart) + replacement + str.substring(position + 1);position -= (token.length - replacement.length);tokenStart = null;}}// 將{},[],()等括起來的部分全部用占位符代替tokenEndChar = tokenStart = null;var tokenDepth = 0, tokenStartChar = null;for (position = 0; position < str.length; position++) {var c = str.charAt(position);if (tokenStart === null) {switch (c) {case "{": tokenStart = position; tokenStartChar = c;tokenEndChar = "}";break;case "(": tokenStart = position; tokenStartChar = c;tokenEndChar = ")";break;case "[": tokenStart = position; tokenStartChar = c;tokenEndChar = "]";break;}}if (c === tokenStartChar)tokenDepth++;else if (c === tokenEndChar) {tokenDepth--;if (tokenDepth === 0) {var token = str.substring(tokenStart, position + 1);tokens.push(token);replacement = "@mass_token_" + (tokens.length - 1) + "@";str = str.substring(0, tokenStart) + replacement + str.substring(position + 1);position -= (token.length - replacement.length);tokenStart = null;}}}//拆解字段,還原占位符的部分var result = [];var keyValuePairs = str.split(",");for (var i = 0, j = keyValuePairs.length; i < j; i++) {var pair = keyValuePairs[i];var colonPos = pair.indexOf(":");if ((colonPos > 0) && (colonPos < pair.length - 1)) {var key = pair.substring(0, colonPos);var value = pair.substring(colonPos + 1);result.push({'key': restoreTokens(key, tokens),'value': restoreTokens(value, tokens)});} else {//到這里應該拋錯吧result.push({'unknown': restoreTokens(pair, tokens)});}}return result;}function ensureQuoted(key) {var trimmedKey = key.trim()switch (trimmedKey.length && trimmedKey.charAt(0)) {case "'":case '"':return key;default:return "'" + trimmedKey + "'";}}// var e = $.normalizeJSON("{aaa:111,bbb:{ccc:333, class:'xxx', eee:{ddd:444}}}");$.normalizeJSON = function (json, insertFields, extra) {//對鍵名添加引號,以便安全通過編譯var keyValueArray = parseObjectLiteral(json),resultStrings = [] ,keyValueEntry, propertyToHook = [];for (var i = 0; keyValueEntry = keyValueArray[i]; i++) {if (resultStrings.length > 0)resultStrings.push(",");if (keyValueEntry['key']) {var key = keyValueEntry['key'].trim();var quotedKey = ensureQuoted(key), val = keyValueEntry['value'].trim();resultStrings.push(quotedKey);resultStrings.push(":");// if(insertFields === true && key === "foreach"){//特殊處理foreach// var array = val.match($.rword);// val = array.shift();// if(array[0] === "as"){//如果用戶定義了多余參數// extra.$itemName = array[1];// extra.$indexName = array[2];// }// }if(val.charAt(0) == "{" && val.charAt(val.length - 1) == "}"){val = $.normalizeJSON( val );//逐層加引號}resultStrings.push(val);if(insertFields == true){//用函數延遲值部分的執行if (propertyToHook.length > 0)propertyToHook.push(", ");propertyToHook.push(quotedKey + " : function() { return " + val + " }")}} else if (keyValueEntry['unknown']) {resultStrings.push(keyValueEntry['unknown']);//基于跑到這里就是出錯了}}resultStrings = resultStrings.join("");if(insertFields == true){resultStrings += ' , "@mass_fields": {'+ propertyToHook.join("") + '}'}return "{" +resultStrings +"}";}}();});

總結

以上是生活随笔為你收集整理的我的MVVM框架 v0.1发布的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

97超碰人| 国产成人精品福利 | 欧洲一区二区三区精品 | 99爱在线观看 | 九九色网 | 国产又粗又长又硬免费视频 | 97在线影视 | 国产成人一区三区 | 深夜免费小视频 | 欧美人体xx | 美女网站在线 | 久久网站av| 亚洲国产精品免费 | 国产日产精品一区二区三区四区的观看方式 | 国产高清视频色在线www | 天堂av在线免费观看 | 国产午夜精品一区二区三区嫩草 | 欧美一二三视频 | 91在线精品视频 | 在线观看免费黄色 | 91精品久久久久久久久 | 日韩精品一区二区不卡 | 婷婷免费在线视频 | 亚洲伊人第一页 | 国产群p| 久久精品电影 | 日日日天天天 | 成人免费视频网址 | 最新极品jizzhd欧美 | 五月婷婷中文网 | 久久婷婷一区 | 一区二区三区中文字幕在线 | 91亚洲精| 久久精品5| 亚洲国产一区二区精品专区 | 在线免费黄 | 国产 日韩 欧美 在线 | 久久成人综合 | 天天曰天天 | 中文字幕精品一区久久久久 | 国产在线观看你懂的 | 丁香婷婷色月天 | 国产精品igao视频网入口 | 中文字幕免费观看全部电影 | 精品国产综合区久久久久久 | 麻豆久久一区二区 | 婷婷视频在线播放 | 草久久精品 | 成 人 黄 色 视频播放1 | 91精品秘密在线观看 | 久久久999精品视频 国产美女免费观看 | 91在线视频播放 | 中文字幕视频在线播放 | 国产午夜精品一区二区三区四区 | 日韩二区在线播放 | 欧美老少交 | 精品国产免费久久 | 视频在线精品 | 成人免费视频观看 | 天天做天天爱天天爽综合网 | 中日韩男男gay无套 日韩精品一区二区三区高清免费 | 91精品久久久久久 | 91网在线 | 在线观看视频97 | 九九热1| 午夜久操 | 福利视频 | 国产小视频在线观看免费 | 在线观看不卡视频 | 欧洲一区二区在线观看 | 2023国产精品自产拍在线观看 | 免费色视频在线 | 天天干夜夜想 | 中文字幕一区二区三区乱码不卡 | 国产日韩在线一区 | 天天夜夜操 | 日本精品久久久一区二区三区 | 久久精品精品电影网 | 97色婷婷成人综合在线观看 | 国际精品久久久久 | 国产美女黄网站免费 | 一级片视频在线 | 中日韩欧美精彩视频 | 国产97视频| 天天操天天射天天插 | 超碰在线中文字幕 | 亚洲 欧美 成人 | 永久免费在线 | 欧洲激情综合 | 911久久香蕉国产线看观看 | 亚洲第一伊人 | 久久久久久久久毛片 | 在线小视频国产 | 天天干,狠狠干 | 亚洲爱视频| 久久欧洲视频 | 国产福利免费在线观看 | av不卡中文字幕 | 中文字幕在线观看视频一区 | 久久久精品 一区二区三区 国产99视频在线观看 | 在线免费观看的av网站 | 久久久久久国产精品久久 | 天堂黄色片 | 福利电影久久 | 丝袜护士aⅴ在线白丝护士 天天综合精品 | 国产三级国产精品国产专区50 | 18女毛片| 国产精品18久久久久久久久久久久 | 一级性av | 99草在线视频 | 久久精品国产亚洲 | 最新免费中文字幕 | 久久在现视频 | 人人看人人草 | 亚洲影院色 | a级国产乱理论片在线观看 特级毛片在线观看 | 国产精品视频线看 | 日韩二区三区在线观看 | 国产美女黄网站免费 | 亚洲精品国偷拍自产在线观看蜜桃 | 人成在线免费视频 | 色99视频| 十八岁以下禁止观看的1000个网站 | 日日日操| 亚洲精品字幕在线 | 国产高清在线a视频大全 | 天天亚洲综合 | 免费看十八岁美女 | 免费成人av电影 | 国产精品欧美激情在线观看 | 亚洲欧洲精品在线 | 久久这里只精品 | 人人爽人人射 | 色悠悠久久综合 | 国产在线观看污片 | 午夜精品导航 | 九九综合久久 | 日韩av中文字幕在线 | 欧洲精品在线视频 | 国产极品尤物在线 | 综合网天天射 | 337p日本大胆噜噜噜噜 | 九月婷婷综合网 | 久热免费在线 | 一区二区三区免费在线观看视频 | 超碰在97| 日韩手机视频 | 久久69av | 精品主播网红福利资源观看 | 久久久精品午夜 | av电影免费在线看 | 亚洲精品高清在线观看 | 久久国产影院 | av在线免费播放网站 | 国产 日韩 中文字幕 | 黄色免费网站下载 | 久久久久久美女 | 成人手机在线视频 | 97人人超碰在线 | 一区二区三区 中文字幕 | 免费看一级特黄a大片 | 91少妇精拍在线播放 | 国产小视频精品 | www.com久久 | 麻豆果冻剧传媒在线播放 | 色网站中文字幕 | 日韩中文在线观看 | 国产主播大尺度精品福利免费 | 亚洲欧美国产精品va在线观看 | 97视频总站 | 五月天婷婷综合 | 天天狠狠| 欧美一二在线 | 免费裸体视频网 | 日韩大片在线免费观看 | 久久9999久久| 国产一区免费视频 | 色婷婷综合久色 | 欧美精品久久久久久 | 亚洲日日射 | 色a在线观看 | 日韩av不卡在线 | 最近中文字幕 | 久久精品—区二区三区 | 色网免费观看 | www欧美xxxx| 国产日产精品久久久久快鸭 | 亚洲国产影院 | 亚洲精品欧美视频 | 国产区精品区 | 久草在线视频网 | 99精品久久只有精品 | 国产亚洲精品久久久久秋 | sesese图片| 天天人人综合 | 国产 日韩 在线 亚洲 字幕 中文 | 久久久久久不卡 | 毛片网站在线看 | 精品久久久久久久久久 | 91九色性视频| 久操视频在线播放 | 日韩偷拍精品 | 久久亚洲在线 | 91cn国产在线 | av大全在线 | 91精品区| 日韩大陆欧美高清视频区 | 韩国一区二区三区视频 | 国产精品久久久免费 | 国产人成在线视频 | 精品久久久久久综合日本 | 国产一级免费在线 | 国产综合激情 | 六月丁香色婷婷 | 黄av在线| 菠萝菠萝在线精品视频 | 国产精品久久久久久久久久久免费看 | 免费高清在线观看成人 | 久久福利综合 | 日韩中文字幕免费电影 | 亚洲丝袜中文 | 白丝av免费观看 | 日韩专区一区二区 | 91精品在线视频观看 | 欧洲在线免费视频 | 伊人久久五月天 | 日韩一级电影在线观看 | 手机在线黄色网址 | 中文字幕中文字幕在线一区 | 国产欧美日韩视频 | 日韩.com| 欧美在线视频一区二区三区 | 精品xxx | 欧美成人一区二区 | 男女男视频 | 久草电影免费在线观看 | 国产乱码精品一区二区三区介绍 | 日韩国产精品一区 | av电影在线免费 | 欧美一级免费黄色片 | 成人黄色电影在线观看 | 免费下载高清毛片 | av女优中文字幕在线观看 | 一级欧美一级日韩 | 我要看黄色一级片 | 亚洲五月六月 | 国产资源网 | 一级黄色电影网站 | 黄色aa久久 | 我要色综合天天 | 精品久久久久久久久久国产 | 免费国产一区二区 | 欧美日韩精品综合 | 国产精品淫片 | 91在线免费看片 | 免费99精品国产自在在线 | 久久久片 | 国产韩国日本高清视频 | 亚洲va在线va天堂 | 国产精品亚洲片夜色在线 | 日日爽视频 | 午夜精品一区二区三区视频免费看 | 首页av在线| 成年人黄色免费看 | 久久精品国产免费看久久精品 | 国产精品扒开做爽爽的视频 | 天天色宗合 | 人人爽夜夜爽 | av成人免费在线看 | 黄色一级大片免费看 | 国产性xxxx| 国产精品黄色 | 黄色av一区| 日韩午夜精品 | 色综合激情网 | 手机av资源 | 国产精品久久久一区二区 | 成人黄色大片 | 国产精品999久久久 久产久精国产品 | 免费高清国产 | 色综合久久久久久中文网 | 欧美日韩色婷婷 | 久草干| 亚洲经典视频 | 久久精品国产免费看久久精品 | 91麻豆精品国产自产在线 | 免费观看黄色av | 黄色软件视频网站 | 国产精品久久久久久久久搜平片 | 热久久视久久精品18亚洲精品 | 深爱婷婷久久综合 | 国产日韩亚洲 | 九九九热精品 | 狠狠操精品 | 欧美成人精品欧美一级乱 | 国内视频一区二区 | av资源网在线播放 | 成人av午夜| 超碰国产在线播放 | 国产一区精品在线 | 国产一级二级av | 99精品一区二区三区 | 高清美女视频 | 日日麻批40分钟视频免费观看 | 久久99国产精品 | 色福利网 | 91福利视频网站 | 久久呀| 在线电影 你懂得 | 欧美一级久久 | 日日婷婷夜日日天干 | 中文字幕精品久久 | 在线视频区| 狠狠色丁香 | 夜夜操天天摸 | 日韩欧美精品一区二区三区经典 | 婷婷网五月天 | 2019中文 | 国产亚洲视频在线观看 | 美女网站黄在线观看 | 久草| 日韩欧美视频在线免费观看 | 精品av网站 | 国产一区视频在线观看免费 | 国产一二区免费视频 | 麻豆影视网 | 亚洲一区二区视频在线 | 久久久久久久久久久久国产精品 | 婷婷在线视频 | 亚洲天堂色婷婷 | 久福利| 免费人成在线观看 | 久久久久久视频 | 久久资源总站 | 成人永久免费 | 日韩精品一区二区三区在线视频 | 午夜av色 | 91精品久久久久久粉嫩 | 天天做日日做天天爽视频免费 | 天天插狠狠干 | 久久99久久99精品免费看小说 | 九九在线视频 | 久草com | 视色网站 | 99 视频 高清 | 一区二区三区日韩在线观看 | 久久伊人综合 | 国产高清视频免费观看 | 江苏妇搡bbbb搡bbbb | 久久黄色网址 | 五月婷在线观看 | 在线免费观看羞羞视频 | 亚洲精品tv久久久久久久久久 | 最新色站 | 天天综合网天天 | 黄色在线免费观看网站 | 午夜视频一区二区三区 | www.av免费| 国产精品区免费视频 | av电影免费在线看 | 丁香六月中文字幕 | 最新av免费| 国产精品毛片久久久久久久久久99999999 | 久久av免费| 色香蕉视频 | 亚洲综合小说 | 中文字幕色网站 | 色吊丝在线永久观看最新版本 | 日韩一区二区三免费高清在线观看 | 天天色天天 | www.av小说| 丁香九月激情 | 日韩免费视频播放 | www.婷婷com | 中文字幕在线播出 | 九九欧美视频 | www..com黄色片 | 99色视频在线 | 三级a毛片 | 国产精品99久久久久久武松影视 | www.夜夜干.com | 国产精品自产拍在线观看桃花 | 一区二区激情视频 | 日本中文字幕在线视频 | 国产精品久久99精品毛片三a | 欧美最猛性xxxxx(亚洲精品) | 91av中文 | 麻豆精品在线视频 | 国产97在线视频 | 久久久久日本精品一区二区三区 | 亚洲视频免费在线 | 亚洲 欧美 日韩 综合 | 日韩有码在线播放 | 91麻豆精品国产91久久久久 | 日韩mv欧美mv国产精品 | 国产在线永久 | 色婷婷导航| 欧美久久久久久久久久久久久 | 国产免费视频在线 | 免费在线观看的av网站 | 日本久久91| a级国产毛片 | 欧美aa级 | 极品美女被弄高潮视频网站 | 99久久精品久久久久久动态片 | 国产免费精彩视频 | 在线韩国电影免费观影完整版 | 久久精品系列 | 免费在线色电影 | av免费电影在线 | 18做爰免费视频网站 | 91完整版 | 九热精品 | 国产视频在线一区二区 | 亚洲综合成人专区片 | 成人在线免费视频观看 | 四虎影视4hu4虎成人 | www·22com天天操 | 久久婷婷色综合 | 在线播放一区二区三区 | 国产五月婷 | 日操干| 在线黄色国产 | 精品国产一区二区三区在线观看 | 亚洲国产片 | 69国产精品视频 | 久久精品国产免费观看 | 91亚·色 | av片子在线观看 | 国产自偷自拍 | 欧美一区二区三区在线看 | 日产乱码一二三区别在线 | 国产成人精品久久二区二区 | 狠狠狠狠狠狠狠狠 | 91成人精品观看 | 亚洲国产中文在线 | 午夜精品久久久 | 综合网成人 | 国产精品成人在线观看 | 黄色大全在线观看 | 中文字幕一区二区三区在线观看 | 婷婷五综合 | 亚洲成a人片在线www | 中文字幕高清在线 | 91在线资源 | 亚洲一片黄| 91人人揉日日捏人人看 | 亚洲成aⅴ人片久久青草影院 | 国产黄在线免费观看 | 久久艹在线 | 亚洲欧美日韩国产精品一区午夜 | 国产在线精品福利 | 久久综合干 | 欧美日韩国产欧美 | 久久午夜国产精品 | 91亚洲影院| 黄色网在线免费观看 | 91刺激视频| 天天干天天操av | 亚洲a资源| 国产精品久久 | 日本中文字幕免费观看 | 六月丁香六月婷婷 | 国产一级视频在线观看 | 狠狠狠干狠狠 | 国产成人福利片 | 少妇高潮流白浆在线观看 | 国内精品小视频 | 五月激情在线 | 色爽网站 | 高清av中文字幕 | 亚洲狠狠| 免费午夜视频在线观看 | www在线免费观看 | 亚洲精品美女久久17c | 久久一区二区三区超碰国产精品 | 蜜桃av综合网| 天堂在线免费视频 | 国产成人免费观看久久久 | 久草视频视频在线播放 | 深夜激情影院 | 91精品国产九九九久久久亚洲 | 国产麻豆果冻传媒在线观看 | 欧美一区二区三区不卡 | 欧美一区视频 | 中文字幕资源网 | 日韩在线观看你懂得 | 欧美最猛性xxx | 国产黄色a | 奇米网777 | 成人动漫精品一区二区 | av成人动漫在线观看 | 日日夜夜噜 | 特级a毛片| 久久综合影视 | 国产精品9区 | 精品久久久久久久久久久久久久久久 | av中文字幕在线观看网站 | 国产精品 999 | 色偷偷97 | 成人黄大片 | 国产成人精品一区一区一区 | 在线视频欧美精品 | 黄色一级免费 | 国产精品不卡av | 亚洲国产日韩一区 | 女人18毛片90分钟 | 国产精品观看在线亚洲人成网 | 九九热精品在线 | 国产不卡视频在线播放 | 午夜精品久久久久久久久久久 | 免费久久视频 | 国产亚洲精品久久久久久无几年桃 | 亚洲成人黄色在线观看 | 成人资源在线 | 成年人电影毛片 | 97在线免费观看视频 | 亚洲第一av在线 | 久久精品电影 | 国内视频一区二区 | 国产在线观看你懂的 | 日韩av高潮| 中文国产字幕在线观看 | 人人爽人人爽人人爽人人爽 | 在线观看免费黄色 | 91完整版在线观看 | 精品国产乱码久久久久 | 欧美黄色特级片 | 天天操夜夜操 | 五月色综合 | 国产精品一区二区三区久久久 | 狠狠狠干 | 精品欧美一区二区三区久久久 | 99视频在线精品免费观看2 | 亚洲区精品 | 亚洲五月婷| 18pao国产成视频永久免费 | 日韩av片免费在线观看 | 成人a视频片观看免费 | 九九免费精品视频在线观看 | 日日综合网 | 精品亚洲视频在线观看 | 99精品黄色片免费大全 | 在线精品视频免费观看 | 亚洲精品玖玖玖av在线看 | 91精品久久久久 | 欧美日韩另类在线观看 | 中文字幕亚洲精品在线观看 | 婷婷激情影院 | 欧美另类视频 | 国产一区成人 | h文在线观看免费 | 久久久久久久久久伊人 | 久久99久久99精品免费看小说 | 日韩在线精品一区 | 亚洲欧美日韩精品一区二区 | 狠狠婷婷 | 日韩专区在线 | 99精品在线免费 | 7777精品伊人久久久大香线蕉 | 欧美日韩国产网站 | 日韩精品一区在线观看 | 色综合久久88色综合天天免费 | 欧美一区二区精美视频 | 在线播放日韩av | 99精品欧美一区二区 | 黄网站a | 欧美一级片在线观看视频 | 国产日韩在线播放 | 欧美日韩1区2区 | 天天躁日日躁狠狠躁av麻豆 | 中文字幕国产视频 | 不卡的av在线播放 | 亚洲人成免费网站 | 国产首页 | 欧美日韩精品在线播放 | 亚洲一区二区视频在线播放 | 精品国产成人在线影院 | 亚州成人av在线 | 国产精品国产精品 | 一级黄色片毛片 | 中文字幕免费在线看 | 精品国产精品久久 | 国产99久久九九精品 | 亚洲精品xxx | 欧美激情精品久久久 | 98精品国产自产在线观看 | 日韩高清不卡一区二区三区 | av在线网站免费观看 | 欧美日韩不卡一区二区三区 | 在线黄色毛片 | 最近中文字幕大全中文字幕免费 | 黄在线免费观看 | 国产黄色片久久 | 久草视频在线资源 | www.玖玖玖| 久久黄色网 | 国产精品成人a免费观看 | a在线一区 | 91精品欧美 | 亚洲男模gay裸体gay | 欧美成人黄色 | 草久在线播放 | 免费看网站在线 | 欧美激情视频一二区 | 日韩在线观看精品 | 日韩免费成人 | 亚洲精品视频在线看 | 欧美精品一区二区三区一线天视频 | 婷婷综合视频 | av免费观看高清 | 99热这里只有精品1 av中文字幕日韩 | 在线免费观看的av | 国产免费一区二区三区网站免费 | 亚洲免费av一区二区 | 亚洲精品中文字幕视频 | 9热精品| 天天操夜操 | 日韩色在线观看 | 高清国产在线一区 | 欧美日韩在线观看一区二区三区 | 亚洲精品永久免费视频 | 国产午夜精品一区二区三区 | 在线观看资源 | 手机看片久久 | 成人小视频在线观看免费 | 亚洲一区动漫 | 欧美日韩裸体免费视频 | 久久久免费精品 | 91视频 - v11av | 亚洲一区动漫 | 亚洲国产日韩精品 | 在线国产一区二区三区 | 久草视频在线资源 | 日韩精品久久久久久久电影99爱 | 国内精品在线看 | 久久久三级视频 | 亚洲丁香日韩 | 伊人伊成久久人综合网站 | 国产婷婷 | 婷婷色中文字幕 | 成人性生活大片 | www天天干| www夜夜| 国产欧美精品xxxx另类 | 免费av一级电影 | 在线成人免费av | 狠狠操操操 | 欧亚日韩精品一区二区在线 | 久久ww| 中文字幕在线影视资源 | 婷婷丁香狠狠爱 | 九色91视频 | 91精选在线| 婷婷激情综合 | 最近日韩免费视频 | 免费a v网站 | 超碰在线97免费 | 亚洲午夜久久久综合37日本 | 91欧美视频网站 | 日韩欧美一区二区在线 | 白丝av在线 | 久久伊人八月婷婷综合激情 | 国产黄a三级三级三级三级三级 | 国产日韩精品一区二区三区在线 | 久久天堂网站 | 亚洲精品乱码久久久久 | 久久国产香蕉视频 | 欧美极品久久 | 99热九九这里只有精品10 | 亚洲精品视频在线免费播放 | 亚洲国产久 | 国内精品久久久久影院优 | 97理论片 | 伊人狠狠色 | 日韩精品一区二区三区视频播放 | 97电影在线| 国产精品久久久久久一区二区 | 精品久久久久久久久久久久久久久久久久 | 亚洲成人黄色在线观看 | 不卡av电影在线观看 | 激情av网址 | 久久伦理 | 日韩影视精品 | 一区二区三区精品在线视频 | 91看片在线观看 | 国产在线不卡一区 | 国产99久久 | 在线观看爱爱视频 | 久久伊人热 | 日韩视频一区二区在线 | 久久国产午夜精品理论片最新版本 | 亚洲精品777 | 九九九国产 | 一区二区三区精品久久久 | 国产 一区二区三区 在线 | 狠狠色狠狠色综合日日92 | 国产精品一区二区三区四 | 日韩动漫免费观看高清完整版在线观看 | 婷婷丁香激情 | 日韩色综合网 | 成年人在线观看免费视频 | 久久久久在线视频 | 天天色成人| 国产超碰97 | 97超碰在线久草超碰在线观看 | 狠狠色丁香婷婷综合久小说久 | 久久亚洲综合国产精品99麻豆的功能介绍 | 中文字幕区 | 亚洲第一中文字幕 | 亚洲黄色小说网址 | 久久在线一区 | 波多野结衣综合网 | 国产不卡在线 | 久久99精品国产一区二区三区 | 一区三区在线欧 | 国产女人18毛片水真多18精品 | 黄色在线看网站 | 欧美人人 | 综合激情av| 爱爱av在线 | 天天玩天天操天天射 | 黄色av成人在线观看 | 久草在线观看视频免费 | 在线国产一区二区三区 | 午夜精品一区二区三区在线观看 | 中文字幕在线视频第一页 | 91大片成人网 | 免费在线观看av网站 | 亚洲一区美女视频在线观看免费 | 日本精品午夜 | 欧美在线一 | 中文字幕中文字幕中文字幕 | 日韩欧美高清视频在线观看 | 91最新视频在线观看 | 国产精品成 | 日韩av综合网站 | 国产精品一区在线观看你懂的 | 国产伦精品一区二区三区… | 91av在线视频免费观看 | 国产一区福利在线 | 日韩在线观看视频一区二区三区 | 成人在线视频你懂的 | 亚洲精品久久久久中文字幕二区 | 亚洲欧洲在线视频 | 综合网婷婷| 最近中文字幕免费av | 成人午夜电影在线观看 | 最近更新中文字幕 | 日本中文乱码卡一卡二新区 | 九九色在线观看 | 天堂在线免费视频 | 欧美国产不卡 | 91视频这里只有精品 | 亚洲成人免费观看 | 亚洲综合黄色 | 操少妇视频 | 久久综合九色综合97_ 久久久 | 91试看| 色网av | 91人人干 | 日日爱影视 | 97国产精品 | 四虎在线观看视频 | 欧美一区二区三区在线看 | 国产在线观看污片 | 国产一级片一区二区三区 | 日韩videos高潮hd | 久久免费视频这里只有精品 | 色婷婷在线视频 | 国产精品字幕 | 欧美一级片 | 欧美亚洲国产一卡 | 在线观看91av | 亚州精品成人 | 日本一区二区三区免费观看 | 日日夜夜网站 | 999精品视频 | 欧美成人91 | 最近中文字幕免费 | 狠狠色2019综合网 | 成人中文字幕+乱码+中文字幕 | 久久精品这里都是精品 | 国产专区在线看 | 欧美视频二区 | 99色网站| .国产精品成人自产拍在线观看6 | 中文字幕一区二区三区四区在线视频 | 国产精品破处视频 | 在线国产日韩 | 久青草电影| 免费网站黄 | 成人影片在线播放 | 国产男女免费完整视频 | 亚洲二区精品 | 在线精品在线 | 一区二区三区在线观看免费 | 少妇bbw揉bbb欧美 | 中文字幕人成乱码在线观看 | 色婷婷综合久久久久 | 最新的av网站| 99色视频在线 | 欧美激情va永久在线播放 | 精品人人爽 | 欧美精品国产综合久久 | 天天综合色 | av电影在线免费 | 午夜视频在线观看网站 | 欧美日韩精品在线播放 | 国产午夜精品av一区二区 | 成人毛片a | 日韩二三区 | 天天躁天天躁天天躁婷 | av电影一区| 国产成人精品在线播放 | 一区二区免费不卡在线 | 在线欧美小视频 | 久久99热这里只有精品 | 成人av一区二区在线观看 | 日本黄色大片免费 | 天天干天天在线 | 色综合天天做天天爱 | 国产又粗又硬又长又爽的视频 | av看片网 | 日韩欧美一区二区三区视频 | 91成人在线观看高潮 | 国产又粗又猛又色又黄网站 | 成人久久久精品国产乱码一区二区 | 久久久精品国产一区二区电影四季 | 国产精品国产三级国产不产一地 | 91在线日韩 | 久草在线91 | 国产精品美乳一区二区免费 | 国产大片免费久久 | 久久久福利视频 | 色综合久久久久综合99 | 国产蜜臀av | 国产精品99久久免费观看 | 欧美色久 | 亚洲精品色 | 亚洲成人av一区 | 国产精品久久久久久久久久久不卡 | 黄色电影网站在线观看 | 国产在线探花 | 欧美激情奇米色 | 久久国产精品99久久久久久进口 | 欧美精品免费一区二区 | 国产精品久久久久毛片大屁完整版 | 婷婷丁香色 | 九九热在线观看视频 | 98超碰在线 | 国产1区在线 | 96亚洲精品久久 | 国产精品免费久久久久影院仙踪林 | 黄色大片国产 | 国产欧美精品在线观看 | 鲁一鲁影院 | 亚洲永久精品一区 | 黄色精品一区 | 中文成人字幕 | 丁香六月天婷婷 | 涩涩网站在线播放 | 国产一区二区在线免费视频 | av黄色免费看 | 久久午夜色播影院免费高清 | 18做爰免费视频网站 | 日日操操 | 久久99爱视频 | 国产精品免费久久久 | 国产精品久久久久久一二三四五 | 国产裸体无遮挡 | 成人免费看电影 | 日韩av手机在线看 | 不卡日韩av | 国产破处在线视频 | 亚洲精品乱码久久久久久蜜桃欧美 | 黄p网站在线观看 | 视频高清 | 国产精品久久久久一区二区国产 | 日日干夜夜草 | 久久精品视频在线 | 91免费视频黄 | 五月婷婷亚洲 | 久久久久久久久久久久久久电影 | 国产亚洲精品久久久久5区 成人h电影在线观看 | 亚洲黄色区| 亚洲精品av在线 | 久久国产精品一二三区 | 久久人人爽人人爽人人片av免费 | 欧美精品亚洲精品日韩精品 | 激情五月激情综合网 | 日韩高清在线一区二区三区 | 日韩精品在线免费播放 | 日本久久久久久久久 | 九九免费精品视频在线观看 | 国产99久久九九精品 | www.激情五月.com | 免费成人av | 久久精品国产免费看久久精品 | 久久国产精品99久久久久 | 日韩精品资源 | 色婷婷激婷婷情综天天 | 成人四虎影院 | 亚洲精品国久久99热 | 最新高清无码专区 | 精品国产久 | 狠狠色丁婷婷日日 | 成人在线视频免费看 | 国产精品成人av久久 | 日韩av一卡二卡三卡 | 最近免费中文字幕mv在线视频3 | 亚洲精品久久在线 | 欧美另类性| 国产在线视频导航 | 国产高清一| 2022国产精品视频 | av免费网页 | 久久艹影院 | 国产精品视频你懂的 | 久久久久久久久久久福利 | 久久99国产精品自在自在app | 久久人人精品 | 久久日本视频 | 久久综合九色九九 | 国产99久久久欧美黑人 | 狠狠色丁香久久婷婷综合五月 | 成人免费xxxxxx视频 | 日韩欧美一区二区三区免费观看 | 69精品视频在线观看 | 人人澡澡人人 | 欧美色综合天天久久综合精品 | 国产高清无线码2021 | av日韩不卡| 国产999精品久久久影片官网 | 久久久99精品免费观看app | 久久久国产精品一区二区三区 | 99精品国产一区二区 | 国产日韩在线播放 | 韩国一区二区三区在线观看 | 久草在线免费电影 | 四虎国产 | 永久免费精品视频网站 | 免费三级黄 | 日本公乱妇视频 | 日韩免费av网址 | av黄色av | 黄色小说免费在线观看 | 欧美人人 | 国产成人99久久亚洲综合精品 | 亚洲爱视频 | 国产免费不卡 | 亚洲视屏在线播放 | 久久久久久久久久久黄色 | 日韩免费在线观看 | 久久久精品国产免费观看同学 | 在线观看国产福利片 | 五月天婷亚洲天综合网鲁鲁鲁 | 一区免费视频 | 97精产国品一二三产区在线 | 91丨九色丨蝌蚪丨老版 | 色资源网免费观看视频 | 国产精品色婷婷视频 | 激情综合久久 | 精品免费久久久久 | 国产一区二区在线播放视频 | 欧美日韩在线免费观看视频 | 麻豆va一区二区三区久久浪 | 婷婷色吧 | 91国内在线视频 | 免费日韩 精品中文字幕视频在线 | 国内精品久久久久久久影视麻豆 | 日韩在线电影一区 | 亚洲欧洲在线视频 | 极品中文字幕 | 亚洲1区在线 | 久久久久伦理电影 | 国产国语在线 | 日韩视频一二三区 | 日韩精品一区二区在线观看 | 亚洲日本激情 | 久久人网| 欧美日韩国产精品一区二区亚洲 | av成人免费 | 日韩专区在线播放 | 麻豆成人精品视频 | 美女av电影 | 在线免费黄色av | 99在线精品视频 | 亚洲,国产成人av | 天天干天天操天天操 | 亚洲va在线va天堂 | 男女激情免费网站 | 日韩二级毛片 | 中文av网 | bbbb操bbbb| 99这里精品 | 国产精品久久久区三区天天噜 | 免费高清在线一区 |