您的位置:首页 > 其它

设计模式知识连载(50)---MVVM模式:

2018-01-12 12:09 477 查看
<body>

<h3>设计模式知识连载(50)---MVVM模式:</h3>
<div>
<p>
模型(Model)-视图(View)-视图模型(ViewModel):为视图层(View)量身定做一套视图模型(ViewModel),并在视图模型(ViewModel)中创建属性和方法,为视图层(View)绑定数据(Model)并实现交互
</p>

</div>

<hr>

<div class="first" data-bind="type : 'slider', data : demo1"></div>
<div class="second" data-bind="type : 'slider', data : demo2"></div>
<div class="third" data-bind="type : 'progressbar', data : demo3"></div>

<script type="text/javascript">

/**
*   模拟数据:
*/
// 带有提示文案的滑动条
var demo1 ={
position : 60,
totle : 200
} ;
// 简易版滑动条
var demo2 ={
position : 20
} ;
// 进度条
var demo3 ={
position : 50
} ;

/**
*   案例一:滚动条与进度条,方式一:初始
*/
// 视图模型层---VM环境
// ~屏蔽压缩报错
~(function () {
// 在闭包中获取全局变量
var window = this || (0, eval) ('this') ;
// 获取页面字体大小,作为创建页面UI尺寸参照物
var FONTSIZE = (function() {
// 获取页面body元素字体大小并转化为整数。
return parseInt(document.body.currentStyle ? document.body.currentStyle['fontSize'] : getComputedStyle(document.body, false)['fontSize']) ;
}) () ;
// 视图模型对象
var VM = (function() {
// 组件创建策略对象
var Method = {
/***
*   进度条组件创建方法
*   dom     进度条容器
*   data    进度条数据模型
**/
progressbar : function(dom, data) {
// 进度条进度完成容器
var progress = document.createElement('div') ;
// 数据模型数据,结构:{position : 50}
var param = data.data ;
// 设置进度完成容器尺寸
progress.style.width = (param.position || 100) + '%' ;
// 为进度条组件添加UI样式
dom.className += 'ui-progressbar' ;
// 进度完成容器元素插入进度条容器中
dom.appendChild(progress) ;
},
/***
*   滑动条组件创建方法
*   dom     滑动条容器
*   data    滑动条数据模型
**/
slider : function(dom, data) {
// 滑动条拨片
var bar = document.createElement('span') ;
// 滑动条进度容器
var progress = document.createElement('div') ;
// 滑动条容量提示信息
var totleText = null ;
// 滑动条拨片提示信息
var progressText = null ;
// 数据模型数据,结构:{position : 60, totle : 200}
var param = data.data ;
// 容器元素宽度
var width = dom.clientWidth ;
// 容器元素横坐标值
var left = dom.offsetLeft ;
// 拨片位置(以模型数据中position数据计算)
var realWidth = (param.position || 100) * width / 100 ;

// 清空滑动条容器,为创建滑动条做准备
dom.innerHTML = '' ;

// 如果模型数据中提供容器总量信息(param.totle),则创建滑动条提示文案
if(param.totle) {
// 容器位置提示文案
text = document.createElement('b') ;
// 拨片位置提示文案
progressText = document.createElement('em') ;
// 设置容器总量提示文案
text.innerHTML = param.totle ;
// 将容器总量提示文案元素添加到滑动条组件中
dom.appendChild(text) ;
// 将拨片位置提示文案元素添加到滑动条组件中
dom.appendChild(progressText) ;
}

// 设置滑动条
setStyle(realWidth) ;
// 为滑动条组件添加UI样式
dom.className += 'ui-slider' ;
// 将进度容器添加到滑动条组件中
dom.appendChild(progress) ;
// 将拨片添加到滑动条组件中
dom.appendChild(bar) ;

// 设置滑动条
function setStyle(w) {
// 设置进度容器宽度
progress.style.width = w + 'px' ;
// 设置拨片横坐标
bar.style.left = w - FONTSIZE / 2  + 'px' ;

// 如果有拨片横坐标
if(progressText) {
// 设置拨片提示文案横坐标
progressText.style.left = w - FONTSIZE / 2 * 2.4 + 'px' ;
// 设置拨片提示文案内容
progressText.innerHTML = parseFloat(w / width * 100).toFixed(2) + '%' ;
}
};

/*创建组件逻辑-------------*/
// 按下鼠标拨片
bar.onmousedown = function() {
// 移动拨片(鼠标光标在页面中滑动,事件绑定给document是为了优化交互体验,是鼠标光标可以在页面中自由移动)
document.onmousemove = function(event) {
// 获取事件源
var e = event || window.event ;
// 鼠标光标相对于滑动条容器位置原点移动的横坐标
var w = e.clientX - left ;
// 设置滑动条
setStyle(w < width ? (w > 0 ? w : 0) : width) ;
}

// 阻止页面滑动选取事件
document.onselectstart = function() {
return false ;
}

// 停止滑动交互(鼠标按键松开)
document.onmouseup = function() {
// 取消文档鼠标光标移动事件
document.onmousemove = null ;
// 取消文档滑动选取事件
document.onselectstart = null ;
}
}
}
}

/***
*   获取视图层组件渲染数据的映射信息
*   dom     组件元素
**/
function getBindDate(dom) {
// 获取组件自定义属性data-bind值
var data = dom.getAttribute('data-bind') ;
// 将自定义属性data-bind值转化为对象
return !! data && (new Function('return ({'+ data +'})')) () ;
}

// 组件实例化方法
return function() {
// 获取页面中所有元素
var doms = document.body.getElementsByTagName('*') ;
// 元素自定义数据句柄
var ctx = null ;
// ui 处理是会向页面中插入元素,此时doms.length会改变,此时动态获取dom.length ;
for(var i = 0; i < doms.length; i++) {
// 获取元素自定义数据
ctx = getBindDate(doms[i]) ;
// 如果元素是UI组件,则根据自定义属性中组件类型渲染该组件
ctx.type &&
4000
amp; Method[ctx.type] && Method[ctx.type](doms[i], ctx) ;
}
}
}) () ;

// 将视图模型对象绑定在Window上,供外部获取
window.VM = VM ;

})() ;

// 处理视图模型对象VM

// 渲染组件
window.onload = function() {
VM() ;
}

</script>

</body>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  设计模式 mvvm模式