kendo-ui的MVVM模式
摘要:
MVVM(Model View ViewModel)是一种帮助开发者将数据从模型分离的设计模式。MVVM的ViewModel负责将数据对象从模型中分离出来,通过这种方式数据就很容易控制数据如何显示在视图上。
创建View-Model对象:
首先我们需要创建一个View-Model对象,他是控制你的数据显示在视图上。
创建对象
var viewModel = kendo.observable({
name: "John Doe",
displayGreeting: function() {
var name = this.get("name");
alert("Hello, " + name + "!!!");
}
});
创建视图
<div id="view">
<input data-bind="value: name" />
<button data-bind="click: displayGreeting">Display Greeting</button>
</div>
然后将对象绑定到视图上
kendo.bind($("#view"), viewModel);
如何工作呢?
input元素的value值是通过data-bind属性绑定到viewModel的name字段,这个绑定是双向的,当改变viewModel的name字段值,视图上input的value值也会被改变。当改变视图上input元素的value值,viewModel的name字段也会被改变。
绑定:
元素通过data-bind属性绑定到viewModel,当你想通过一个对象绑定到视图上,你可以像下面这样定义视图模型
<div data-bind="text: person.name">
</div>
<script>
var viewModel = kendo.observable({
person: {
name: "John Doe"
}
});
kendo.bind($("div"), viewModel);
</script>
data-bind还支持的属性有source, html, attr, visible, enabled等,支持多个属性,以逗号分隔。
注意:
绑定不是javascript,像下面这样的绑定就是不对的
<div data-bind="text: person.name.toLowerCase()"></div>
ObservableObject:
kendo.data.ObservableObject是MVVM模式中非常重要的一部分,它支持跟踪变化和通知用户发生变化,所有的视图模型对象都继承它。
创建ObservableObject
var viewModel1 = new kendo.data.ObservableObject( {
field1: "value1",
field2: "value2"
});
var viewModel2 = kendo.observable( {
field1: "value1",
field2: "value2"
});
上面两种方式都可以创建ObservableObject
注意:视图模型必须在定义ObservableObject之后使用,否则无效。
设置与获取属性值:
我们可以通过viewModel对象来获取属性值,如下:
var viewModel = kendo.observable({
name: "John Doe"
});
viewModel.set("name", "Jane Doe"); //set the "name" field to "Jane Doe"
var name = viewModel.get("name");
alert(name); // shows "Jane Doe"
关键字this:
我们可以通过this来获取视图模型的其他属性值,如下:
<span data-bind="text: fullName"></span>
<script>
var viewModel = kendo.observable({
firstName: "John",
lastName: "Doe",
fullName: function() {
return this.get("firstName") + " " + this.get("lastName");
}
}); kendo.bind($("span"), viewModel);
</script>
data-bind属性:
attr:
attr可以用来绑定DOM元素的属性,例如:href、title等,对于多个属性我们可以用对象来绑定,如下:
<img id="logo" data-bind="attr: { src: imageSource, alt: imageAlt }" />
<script>
var viewModel = kendo.observable({
imageSource: "http://www.telerik.com/image/kendo-logo.png",
imageAlt: "Kendo Logo"
});
kendo.bind($("#logo"), viewModel);
</script>
显示到视图上就会变成如下:
<img id="logo" src="http://www.telerik.com/image/kendo-logo.png" alt="Kendo Logo"" />
checked:
checked属性使用来选择复选框或者单选框,属性值为true或false,如下:
<input type="checkbox" data-bind="checked: isChecked" />
<script>
var viewModel = kendo.observable({
isChecked: false
}); kendo.bind($("input"), viewModel);
</script>
对于多个复选框,根据value值来决定选中哪一个复选框,属性值是一个数组,如下:
<input type="checkbox" value="Red" data-bind="checked: colors" />
<input type="checkbox" value="Green" data-bind="checked: colors" />
<input type="checkbox" value="Blue" data-bind="checked: colors" />
<script>
var viewModel = kendo.observable({
colors: ["Red"]
}); kendo.bind($("input"), viewModel);
</script>
单选框,如下:
<input type="radio" value="Red" name="color" data-bind="checked: selectedColor" />
<input type="radio" value="Green" name="color" data-bind="checked: selectedColor" />
<input type="radio" value="Blue" name="color" data-bind="checked: selectedColor" />
<script>
var viewModel = kendo.observable({
selectedColor: "Green"
}); kendo.bind($("input"), viewModel);
</script>
注意:单选框应该有相同的name值,checked只适合可以勾选的元素。
click:
click属性将绑定一个方法到视图模型上,当点击这个DOM元素该方法将会被调用。
<div id="view">
<span data-bind="click: showDescription">Show description</span>
<span data-bind="visible: isDescriptionShown, text: description"></span> <script>
var viewModel = kendo.observable({
description: "Description",
isDescriptionShown: false,
showDescription: function(e) {
// show the span by setting isDescriptionShown to true
this.set("isDescriptionShown", true);
}
}); kendo.bind($("#view"), viewModel);
</script>
</div>
我们也可以通过events属性来绑定click事件,如下:
<span data-bind="click: clickHandler"></span>
<span data-bind="events: { click: clickHandler }"></span>
阻止事件冒泡
我们可以使用stopPropagation来阻止click事件冒泡,如下:
<span data-bind="click: click">Click</span>
<script>
var viewModel = kendo.observable({
click: function(e) {
e.stopPropagation();
}
}); kendo.bind($("span"), viewModel);
</script>
阻止默认事件
使用preventDefault方法来阻止浏览器默认行为。
<a href="http://example.com" data-bind="click: click">Click</span>
<script>
var viewModel = kendo.observable({
click: function(e) {
// stop the browser from navigating to http://example.com
e.preventDefault();
}
}); kendo.bind($("a"), viewModel);
</script>
custom:
kendo MVVM提供自定义绑定属性,这有利于我们自己做一些扩展。我们可以通过kendo.data.Binder来注册一个属性。
单项绑定
这种自定义属性当视图模型的属性值改变时,DOM元素将被更新,但是当DOM元素改变时并不会更新视图模型属性值。如下:
<script>
kendo.data.binders.slide = kendo.data.Binder.extend({
refresh: function() {
var value = this.bindings["slide"].get(); if (value) {
$(this.element).slideDown();
} else {
$(this.element).slideUp();
}
}
}); var viewModel = kendo.observable({
slideValue: true
}); kendo.bind(document.body, viewModel);
</script> <div id="target" data-bind="slide: slideValue">
One Big Orange Square.
</div>
双向绑定
这种自定义的属性支持双向绑定,即当DOM元素改变时会触发视图模型的改变,当视图模型属性值改变时会触发DOM元素的改变。如下:
<script>
kendo.data.binders.numericValue = kendo.data.Binder.extend({
init: function(element, bindings, options) {
//call the base constructor
kendo.data.Binder.fn.init.call(this, element, bindings, options); var that = this;
//listen for the change event of the element
$(that.element).on("change", function() {
that.change(); //call the change function
});
},
refresh: function() {
var that = this,
value = that.bindings["numericValue"].get(); //get the value from the View-Model $(that.element).val(value); //update the HTML input element
},
change: function() {
var value = this.element.value;
//in this example the View-Model will be updated only if the value of the input is a number
if (!isNaN(value)) {
this.bindings["numericValue"].set(value); //update the View-Model
}
}
}); //View-Model source
var viewModel = kendo.observable({
number: 10
}); kendo.bind(document.body, viewModel);
</script> <!-- View source -->
<input data-bind="numericValue: number" />
Input value: <span data-bind="text: number" />
组件绑定
这种自定义属性支持当视图模型属性值改变时会触发组件的改变。如下:
//the following example demonstrates how to bind the max value of a NumericTextBox widget
kendo.data.binders.widget.max = kendo.data.Binder.extend({
init: function(widget, bindings, options) {
//call the base constructor
kendo.data.Binder.fn.init.call(this, widget.element[0], bindings, options);
},
refresh: function() {
var that = this,
value = that.bindings["max"].get(); //get the value from the View-Model
$(that.element).data("kendoNumericTextBox").max(value); //update the widget
}
}); <!-- View source -->
<input data-role="numerictextbox" id="numeric" data-bind="value: value, max: max" />
自定义属性的方法讲解
init
init类似于构造函数,如果这个函数被重写了,其基本构造函数首先被显示调用。
refresh
refresh负责更新DOM元素。当视图模型的属性值改变时,它会被执行。
change
change负责更新视图模型的属性值。DOM元素发生变化时,它会被执行。
disabled:
disabled是禁用DOM元素,属性值为true或false。适合的DOM元素为:input、select、textarea。当DOM元素的disabled属性值被设置为true时,则他的value值不能被改变。
<div id="view">
<input type="text" data-bind="value: name, disabled: isNameDisabled" />
<button data-bind="click: disableInput">Disable</button> <script>
var viewModel = kendo.observable({
isNameDisabled: false,
name: "John Doe",
disableInput: function() {
this.set("isNameDisabled", true);
}
}); kendo.bind($("#view"), viewModel);
</script>
</div>
注意:0, null, undefined,"",''都会被当成false。
enable:
与disabled相同,功能相反。
events:
events将视图模型定义的方法绑定到DOM元素上,当对应事件在DOM元素发生时,该方法会被执行。如下:
<div id="view">
<span data-bind="events: { mouseover: showDescription, mouseout: hideDescription }">Show description</span>
<span data-bind="visible: isDescriptionShown, text: description"></span>
</div>
<script>
var viewModel = kendo.observable({
description: "Description",
isDescriptionShown: false,
showDescription: function(e) {
// show the span by setting isDescriptionShown to true
this.set("isDescriptionShown", true);
},
hideDescription: function(e) {
// hide the span by setting isDescriptionShown to false
this.set("isDescriptionShown", false);
}
}); kendo.bind($("#view"), viewModel);
</script>
html:
html是将视图模型定义的值以html的形式插入到DOM元素内。如下:
<span data-bind="html: name"></span>
<script>
var viewModel = kendo.observable({
name: "<strong>John Doe</strong>"
}); kendo.bind($("span"), viewModel);
</script>
结果为
<span><strong>John Doe</strong></span>
注意:并不是所有DOM元素都支持html属性,比如table。他只适合内部没有固定结构的html元素。
invisible:
invisible控制DOM元素是否显示。属性值true或false,当设置为true时,DOM元素将被隐藏,对应css的display属性将被设置为none。如下:
<div id="view">
<div data-bind="invisible: isInvisible">some content
</div>
<button data-bind="click: show">Show</button>
</div>
<script>
var viewModel = kendo.observable({
isInvisible: true,
show: function() {
this.set("isInvisible", false);
}
}); kendo.bind($("#view"), viewModel);
</script>
初始div元素是隐藏的,因为isInvisible设置为true,当点击按钮时,isInvisible被设置为false,div元素显示。
source:
source用来渲染DOM元素的模板,模板是通过data-template属性来指定,属性值为模板的id,如果未指定则会根据元素的name值。如果视图模型中的属性值为数组时,会自动循环每一项并渲染模板到DOM元素内。
<ul data-template="ul-template" data-bind="source: products">
</ul>
<script id="ul-template" type="text/x-kendo-template">
<li>
id: <span data-bind="text: id"></span>
name: <span data-bind="text: name"></span>
</li>
</script>
<script>
var viewModel = kendo.observable({
products: [
{ id: 1, name: "Coffee" },
{ id: 2, name: "Tea" },
{ id: 3, name: "Juice" }
]
}); kendo.bind($("ul"), viewModel);
</script>
结果为
<ul>
<li>
id: <span>1</span>
name: <span>Coffee</span>
</li>
<li>
id: <span>2</span>
name: <span>Tea</span>
</li>
<li>
id: <span>3</span>
name: <span>Juice</span>
</li>
</ul>
如果数组中不全是对象,则可以使用this代替当前属性值,如下:
<ul data-template="ul-template" data-bind="source: products">
</ul>
<script id="ul-template" type="text/x-kendo-template">
<li data-bind="text: this"></li>
</script>
<script>
var viewModel = kendo.observable({
products: [ "Coffee", "Tea", "Juice" ]
}); kendo.bind($("ul"), viewModel);
</script>
结果为
<ul>
<li>Coffee</li>
<li>Tea</li>
<li>Juice</li>
</ul>
给select元素设置source属性:
<select data-text-field="name" data-value-field="id"
data-bind="source: products"></select>
<script>
var viewModel = kendo.observable({
products: [
{ id: 1, name: "Coffee" },
{ id: 2, name: "Tea" },
{ id: 3, name: "Juice" }
]
}); kendo.bind($("select"), viewModel);
</script>
显示在视图上为
<select>
<option value="1">Coffee</option>
<option value="2">Tea</option>
<option value="3">Juice</option>
</select>
style:
style属性用来设置DOM元素的样式,如下:
<span data-bind="style: {color: priceColor, fontWeight: priceFontWeight},
text: price"></span>
<script>
var viewModel = kendo.observable({
price: 42,
priceColor: function() {
var price = this.get("price");
if (price <= 42) {
return "#00ff00";
} else {
return "#ff0000";
}
},
priceFontWeight: function() {
var price = this.get("price");
if (price <= 42) {
return "bold";
} else {
return ""; //will reset the font weight to its default value
}
}
});
kendo.bind($("span"), viewModel);
</script>
结果为
<span style="color: #00ff00; font-weight: bold">42</span>
注意:对于这种font-weight, font-size, background-color应该使用驼峰格式。
text:
text用来设置元素文本内容,如下:
<span data-bind="text: name"></span>
<script>
var viewModel = kendo.observable({
name: "John Doe"
}); kendo.bind($("span"), viewModel);
</script>
结果为
<span>John Doe</span>
value:
value属性用来设置DOM元素的value值,所以他只适合带有value属性的DOM元素,比如input, textarea和select。此属性是双向绑定的,即任何一方改变都会触发另一方的改变。如下:
<div id="view">
<input data-bind="value: inputValue" />
<textarea data-bind="value: textareaValue"></textarea>
</div>
<script>
var viewModel = kendo.observable({
inputValue: "Input value",
textareaValue: "Textarea value"
}); kendo.bind($("#view"), viewModel);
</script>
注意:如果DOM元素改变并不是实时触发视图模型的属性值改变,而是当DOM元素变换结束之后。
我们可以通过data-value-update属性控制什么时候更新视图模型,如下:
<div id="view">
<input data-value-update="keyup" data-bind="value: inputValue" />
</div>
<script>
var viewModel = kendo.observable({
inputValue: "InputValue"
}); kendo.bind($("#view"), viewModel);
</script>
上面的代码是当我们在输入框松开键盘之后就更新视图模型。
对于下拉选择,我们可以像下面这样
<select data-role="dropdownlist" data-option-label="Select product..." data-value-primitive="true"
data-value-field="id" data-text-field="name" data-bind="value: selectedProductId, source: products">
</select>
<script>
var viewModel = kendo.observable({
selectedProductId: null,
products: [
{ id: 1, name: "Coffee" },
{ id: 2, name: "Tea" },
{ id: 3, name: "Juice" }
]
}); kendo.bind($("select"), viewModel);
</script>
visible:
与invisible类似,功能相反。
小结:
MVVM解耦了视图与模型,我们只需要在模型中写好逻辑即可。这种模式简化了我们的开发,提高开发效率。input,select,textarea的值用value,插入html用html,文本用text,checkbox和radio用checked。
kendo-ui的MVVM模式的更多相关文章
- kendo ui 实现MVVM
MVVM model----view model----model 实现页面和model之间的动态绑定 grid 支持 events source visib ...
- Web UI开发推荐!Kendo UI for jQuery自定义小部件——使用MVVM
Kendo UI for jQuery最新试用版下载 Kendo UI目前最新提供Kendo UI for jQuery.Kendo UI for Angular.Kendo UI Support f ...
- Kendo UI开发教程(16): Kendo MVVM 数据绑定(五) Events
本篇和Kendo UI开发教程(14): Kendo MVVM 数据绑定(三) Click类似,为事件绑定的一般形式.Events绑定支持将ViewModel的方法绑定到DOM元素的事件处理(如鼠标事 ...
- Kendo UI for jQuery使用教程:使用MVVM初始化(二)
[Kendo UI for jQuery最新试用版下载] Kendo UI目前最新提供Kendo UI for jQuery.Kendo UI for Angular.Kendo UI Support ...
- Kendo UI for jQuery使用教程:使用MVVM初始化(一)
[Kendo UI for jQuery最新试用版下载] Kendo UI目前最新提供Kendo UI for jQuery.Kendo UI for Angular.Kendo UI Support ...
- HTML5 UI框架Kendo UI Web中如何创建自定义组件(二)
在前面的文章<HTML5 UI框架Kendo UI Web自定义组件(一)>中,对在Kendo UI Web中如何创建自定义组件作出了一些基础讲解,下面将继续前面的内容. 使用一个数据源 ...
- Web界面开发必看!Kendo UI for jQuery编辑功能指南第一弹
Kendo UI for jQuery最新试用版下载 Kendo UI目前最新提供Kendo UI for jQuery.Kendo UI for Angular.Kendo UI Support f ...
- 不知如何摧毁Kendo UI for jQuery小部件?这份指南不得不看
[Kendo UI for jQuery最新试用版下载] Kendo UI目前最新提供Kendo UI for jQuery.Kendo UI for Angular.Kendo UI Support ...
- Kendo UI Grid 使用总结
Kendo UI Grid控件的功能强大,这里将常用的一些功能总结一下. Kendo UI Grid 固定列 在使用Gird控件显示数据时,如果数据列过多,会出现横向滚动条,很多情况下,我们希望某些列 ...
- MVVM模式解析和在WPF中的实现(五)View和ViewModel的通信
MVVM模式解析和在WPF中的实现(五) View和ViewModel的通信 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 M ...
随机推荐
- win10开始菜单打不开,右下角时间点不开等问题
服务--“User Manager",启动后,重启桌面进程
- java中反向转义org.apache.commons.lang3.StringEscapeUtils.unescapeJava
工具类中包含类反向转义的方法: eorderHistory.setSubPrintTemplates(StringEscapeUtils.unescapeJava(eorderHistory.getS ...
- hbase 学习(十三)集群间备份原理
集群建备份,它是master/slaves结构式的备份,由master推送,这样更容易跟踪现在备份到哪里了,况且region server是都有自己的WAL 和HLog日志,它就像mysql的主从备份 ...
- android开发(31) 动画演示 - 从页面底部向上弹出dialog,消失时逐渐向下
我想实现一个效果,从底部向上逐渐弹出.如下图所示: 1.点击 显示 按钮时,一个dialog对话框从底部慢慢向上弹出. 2.关闭dialog时, dialog缓慢的移动向底部消失.很平滑的效果. ...
- sql server 2012 删除服务器名称
SQL Server 2008 R2及以前版本: http://blog.csdn.net/downmoon/article/details/5678468 SQL Server 2012: 删除这两 ...
- Redis哈希
Redis的哈希值是字符串字段和字符串值之间的映射,所以他们是表示对象的完美数据类型 在Redis中的哈希值,可存储超过400十亿键值对. 例子 redis 127.0.0.1:6379> HM ...
- PCL采样一致性算法
在计算机视觉领域广泛的使用各种不同的采样一致性参数估计算法用于排除错误的样本,样本不同对应的应用不同,例如剔除错误的配准点对,分割出处在模型上的点集,PCL中以随机采样一致性算法(RANSAC)为核心 ...
- Java容器有哪些?
网易面试: 问:Java容器有哪些,你聊一聊吧 Java容器: 数组,String,java.util下的集合容器 数组长度限制为 Integer.Integer.MAX_VALUE; String的 ...
- L0、L1及L2范数
L1归一化和L2归一化范数的详解和区别 https://blog.csdn.net/u014381600/article/details/54341317 深度学习——L0.L1及L2范数 https ...
- 近期小结 之 Servlet规范及HTTP
最近认真看了下Servlet 3.1的规范,略有收获,如下: 如果客户端不指定编码,Servlet容器必须使用ISO-8859-1编码来处理,且不能添加相应编码信息. Servlet 3 可以手动开启 ...