Kendo mvvm (UI)项目开发指南
Kendo mvvm 项目开发指南kendo 的mvvm 是最早使用mvvm模式的的一种前端架构技术,也是非常优秀的一款mvvm组件,主要是欧美和印度人喜欢使用。后来流行的vue与react很多mvvm开发模式和设计理念都是来源和借鉴了kendo 的mvvm思想。通过对kendo的mvvm学习,我们可以更容易的掌握和理解前端mvvm使用与演变过程,可以让读者更好的了解和学习前端的mvvm开发模式
Kendo mvvm 项目开发指南
kendo 的mvvm 是最早使用mvvm模式的的一种前端架构技术,也是非常优秀的一款mvvm组件,主要是欧美和印度人喜欢使用。后来流行的vue与react很多mvvm开发模式和设计理念都是来源和借鉴了kendo 的mvvm思想。通过对kendo的mvvm学习,我们可以更容易的掌握和理解前端mvvm使用与演变过程,可以让读者更好的了解和学习前端的mvvm开发模式。kendo 非常符合外国软件工程们开发逻辑,但是我们中国人学习起来多多少少总有点格格不入的感觉。
第一章 启动调试工程
学习kendo mvvm模式需要下载作者为大家提供的kendo练习代码,这样可以方便大家更好的理解kendo使用和本文的示例代码。大家可以在下载的练习示例代码中进行调试与实验方便更快的掌握kendo mvvm编程思想与编程技巧。
项目的示例代码下载地址:https://pan.baidu.com/s/1Q6pbC2SR70HKCeVXgOGUPQ
提取代码:1234
项目结构
打开练习kendoDome项目,可以看到以下文件与文件件。
kendoDome
|--dist //编译生成的代码保存在这个文件夹下,
| //在webpack.config.js中设置
|--images //工程使用到的公共图片
|--libs //html页面中引入的js第三方架构包
|--node_modules //node工程开发类包
|--src //工程业务逻辑代码
|--styles //工程业务样式
|--.eslintrc //工程代码质量监控配置文件
|--package.json //node工程配置文件
|--sonar-projec.properties //代码检测配置文件
|--tsconfig.json //typescript 工程配置文件
|--webpack.config.js //打包,编译,开发测试运行配置文件
启动运行工程项目
进入到kendoDome项目目录中,输入npm run dev 命令启动项目,进入到开发模式中。
cd ./kendoDome
npm run dev
路由routes设置
在项目工程中routes.ts文件为路由配置类负责配置所有项目模板与业务逻辑类路径引用与全局调用。在src文件夹下找到routes.ts文件。
src
|--routes.ts 路由控制类
如果需要新增示例模块,在路由中配置自己代码引用与模块地址,并建立它们的对应关系。
import zhttest1 from './zhtbs/test1/index';//业务连接类地址
export const routes: Route[] = [ //路由地址
//测试例子
{
url: '/zhtbs/test1',//菜单中引用路径
callback: zhttest1,
}
];
菜单设置
路由信息配置完成后,我们需要在菜单类中将这组业务引用配置到框架的菜单中来,我们在src文件夹中的home文件夹下找到home.ts 类。
src
|--home
|---home.ts //菜单主体框架代码
在home.ts类中设置菜单结构。找到data 属性元素按照对应数据结构关系设置菜单内容。
const data= [
{name:'项目一',
subMenus:[
{name:'菜单一',route:'/zhtbs/test1'},<--------------------------- |
{name:'菜单二',route:'/zhtbs/test7'} |
]}, |
{name:'项目二', |
subMenus:[ |
{name:'菜单三',route:'/zhtbs/test8'} |
]} |
]; |
routes.ts(路由类) |
------------------------------------------------ |
import zhttest1 from './zhtbs/test1/index';//业务连接类地址 |
export const routes: Route[] = [ //路由地址 |
{ |
url: '/zhtbs/test1',//菜单中引用路径 <-----------------------------|
callback: zhttest1,
}
];
项目url访问代理设置
在项目的webpack.config 文件中设置外部服务访问url代理设置。
devServer: {
port: 8089,
proxy: {
'/oauth': {
target: 'http://localhost:8888/',
},
//服务代理的web项目的地址
'/zhtbs': {
target: 'http://localhost:8077/',
pathRewrite: { '^/zhtbs': ''},
},
'/img': {
target: 'http://localhost:8888/'
},
},
},
第二章 初始化mvvm创建一个业务结构
每组业务分别有4个文件组成
index.ts //连接组合器 类似于web 中action和Controller 概念
Model.ts //数据模型 脚本与html数据对应关系
template.hbs //视图模板 等于html功能
ViewModel.ts //业务逻辑 所有业务脚本
他们的业务逻辑关系组成
index.ts 类是路由进入接口,路由通过自己定义的引用路径属性,来访问到每个应业务对应的index.ts类中。
在index.ts类要返回一个ViewWithTitle类型的对象引用,这个ViewWithTitle类对象包含了这组业务的视图,业务逻辑,数据模型等功能。
ViewWithTitle 对象结构 { title: ‘标题’, 模型连接器}
找到练习一我们主要使用到了index.ts ,template.hbs,ViewModel.ts来建立一组业务关系。
kendoDome
|--src //工程代码起始目录
|--zhtbs //逻辑代码包
|--test1 //练习一
index.ts业务连接类 (例子1)
1 定义业务逻辑模型类的引用 const vm = new ViewModel();
2 创建视图模板与业务逻辑模型类绑定关系 ,这个绑定关系需要使用到kendo.View 类将视图与逻辑进行绑定。
我们将这种绑定关系称为模型连接器。
3 返回ViewWithTitle 引用 ,ViewWithTitle 对象结构 { title: ‘标题’, 模型连接器}
import template from './template.hbs';
import { mainHeight } from '../../globals';
import ViewModel from './ViewModel';
export default function initIndex(): ViewWithTitle {
const vm = new ViewModel();//->业务逻辑引用
//将模板与事件逻辑类绑定在一起
// template(视图) > ViewModel(逻辑代码)
// 视图逻辑绑定类 kendo.View (template({模板初始参数})) , (model: vm)
const view = new kendo.View( //->定义业务连接器
template({}), //-> 视图
{
model: vm, //->业务逻辑类
init:function(){
console.log( '欢迎来到测试一');
}
}
);
return { title: '测试一', view };
}
ViewModel.ts 业务逻辑类
这个类非常重要,所有视图模板上的数据,事件,业务逻辑都来源于这个类。这个完成了整租业务的百分之80%的业务代码。还复制通过绑定数据模型达到与视图模板数据通信的功能。
1 一定要继承kendo.data.ObservableObject 类,在项目应用中通常继承kendo.data.ObservableObject 的子类,而不会直接接触kendo.data.ObservableObject类进行业务操作。
2 创建构造函数constructor(){}
3 创建业务方法
//继承kendao基础类
export default class ViewModel extends kendo.data.ObservableObject {
//构造函数
constructor() {
super();
super.init(this);
}
public onfind(): void {//->定义业务方法
alert(1);
}
}
template.hbs 模图模板
模板的语法使用了handlebars js模板。
在index.ts程序中定义了handlebars需要引入的数据结构。通过new kendo.View 对象将模板数据和模板事件绑定在一起。
在index.ts中定义模板使用到的JSON变量情况
const view = new kendo.View( //->定义业务连接器
template({'name':'欢迎来到测试一'}),<--------------------- |
{ | 数据和事件
model: vm, <-------------------------------------- |绑定业务类
init:function(){ |
console.log( '欢迎来到测试一'); |
} |
} |
); |
|
ViewModel.ts(业务逻辑类) |
------------------------------------------------ |
export default class ViewModel extends <------------------------|业务类定义
kendo.data.ObservableObject {//继承 |
//构造函数 |
constructor() { |
super(); |
super.init(this); |
} |
public onfind(): void {//->定义业务方法 <---------------------|onfind
alert('我的第一个事件'); |
} |
} |
template.hbs(视图模板) |
------------------------------------------------------- |
<h1>{{name}}</h1> <-----------------------------|绑定数据
<button type="button" data-bind="click:onfind">查询</button> <--|绑定事件onfind
Model.ts 数据模型
在逻辑类中定义数据模型的对象引用,通过数据模型的引用将数据与模板页面中html元素信息进行绑定,达到联动的效果。
数据模型用于和服务器进行交换数据。数据模型用于ajax与服务后端进行操作使用到的数据结构,与服务器上的业务数据进行映射对应关系。
//对应数据源和页面关系 服务器返回参数
const MainModel = kendo.data.Model.define({//设置kendoUI中组件数据对应关系
id: 'id',
fields: {
id: { type: 'string', editable: false, nullable: true}
},
});
//页面from 数据传提参数给服务器
class QueryForm extends kendo.data.ObservableObject {
constructor() {
super();
super.init(this);
}
}
export { MainModel, QueryForm };
kendo.data.Model 继承kendo.data.ObservableObject 类,在kendo中所有数据模型都是ObservableObject 类的子类。ViewModel.ts 业务逻辑类也继承了ObservableObject 类,所以 ViewModel 类也具备一个数据模型的功能。我们也可以直接使用ViewModel 中this.set(),get()方法来定义数据属性内容。
ViewModel 类中定义数据模型
this.set('name','a1');
this.get('name');
-
所有的Kendo ui 组件数据相互都是kendo.data.Model 类型,也是 kendo.data.ObservableObject的子类。
-
kendo.data.ObservableObject 是所有kendo MVVM 逻辑类的父类,里面可以装入,逻辑方法,数据属性等。
-
要开始使用MVVM模式,您需要创建一个View-Model。视图模型是一个可观察的对象。该对象具有属性和方法。每个属性都将绑定到HTML中的某些内容。在MVVM中,此绑定是双向的,这意味着,如果UI上的绑定发生更改,则模型也会更改,反之亦然
第三章 列表 grid UI 操作
Grid UI简介(例子2)
grid组件是kendo中最常用到的UI组件,它同时也是最复杂的组件之一。我们为了能熟练的掌握grid UI需要熟悉以下几个概念。
DataSource: 它是用来与本地 kendo组件进行数据交互的数据源。它可以将本地数据或远程服务器数据(ajax访问)装入到 自身的数据源中,在将数据和kendo组件进行绑定。它本身也提供了几个ajax方法,通过对这几些方法的重载用户可以定义自己的方法。来实现远程http操作,请求从远程数据服务检索数据并将其提交给远程数据服务。
Grid 组件功能: 将DataSource数据绑定给kendo grid组件,grid组件生成对应的表格数据,我们可以通过空手grid组件的属性来调整表格的样式与功能。
我在视图模板中使用grid 过程是在ViewModel.ts 类中定义一个数据源,在 template.hbs视图模板中定义一个grid ui组件,在将他们两个绑定在一起。
ViewModel.ts定义
ViewModel.ts(逻辑类)
----------------------------------------------------------------------------
export default class ViewModel extends kendo.data.ObservableObject {
public dataSource: kendo.data.DataSource;//创建数据源引用
//构造函数
constructor() {
super();
//数据源实现
this.dataSource=new kendo.data.DataSource({data:<------------------|
[ |
{name:'z1','age':12,'bz':'2222'}, | {name:'z2','age':1333,'bz':'2222'} |
] |
});//创建本地数据源 |
//数据是json 形式装载 data属性中 |
} |
public find():void{ |
this.dataSource.read();//查询生产列表数据 |
} |
} |
template.hbs(视图) |
---------------------------------------------------------------------------|
<div class="mypage"> |
<button type="button" data-bind="click:find">查询</button> |
//定义组件类型 data-role=grid(列表) |
<div data-role="grid" data-selectable="multiple,row" |
data-columns="[ //表行列与数据源内容对应关系,列的基本属性设置 |
{ field: 'name', title: '名字', width:150 }, |
{ field: 'bz', title: '备注', width:200 }, |
]" data-bind="source:dataSource" //绑定数据源在逻辑类中的数据源名称 <----------|
class="customGrid"
style="height:500px; margin-top:10px;"
id="grid">
</div>
Grid UI 行列属性设置 (例子3)
通过表格中的data-columns属性来设置表格中的标题,列宽,列数据与dataSource对应关系等功能。data-columns配置内容对应dataSource中data属性的json数组对象,将dataSource中data属性的json数据读取到表格的对应列中。
- 参考代码中练习二
DataSource与data-columns 中field对应关系
ViewModel.ts(逻辑类)
--------------------------------------------------------------------------------
export default class ViewModel extends kendo.data.ObservableObject {
public dataSource: kendo.data.DataSource;//创建数据源引用
//构造函数
constructor() {
super();
//数据源实现
this.dataSource=new kendo.data.DataSource({data:
[
{
name:'z1', //对应data-columns中field: 'name' -------------------
age:12, |
bz:'2222' //对应data-columns中field: 'bz'-------------------|
}, | |
{ | |
name:'z2', age:1333, | |
bz:'2222'} | |
] | |
});//创建本地数据源 数据是json 形式装载 data属性中 | |
} | |
} | |
ViewModel.ts(逻辑类) | |
-------------------------------------------------------------------- | |
<div data-role="grid" // UI 组件类型,grid组件 | |
data-columns="[ | |
{ field: 'name',//this.dataSource中name属性对应的值 <—|——|
title: '名字',//列名称 |
width:150 //列表宽 |
}, |
{ field: 'bz', //this.dataSource中bz属性对应的值 <------|
title: '备注',
width:200
}
]"
data-bind="source:dataSource"
style="height:300px; margin-top:10px;"
id="grid" />
Kendo表格UI中,行列有很多属性可以满足用户的业务变化。常用有设置行列的自定义css,组合标题头,行列事件,自定义列内容模板等等很多实用的功能,需要开发者熟练掌握和运用。
列属性功能
属性名称 | 介绍 |
---|---|
attributes | 列css样式设置 |
columns | 复合标题头,列组合 |
command(基础) | 系统行列编辑模式设置 |
command.click | 自定义行列事件(非常好用) |
command其他属性 | 行列编辑模式其他属性 |
template | 列模板设置(自定义列内容) |
format | 列的格式设置(日期) |
locked | 行列冻结 |
sticky | 列宽度联动 |
attributes样式
attributes: 设置内容列css样式内容.列字体大小,颜色,样式。
<div data-role="grid" // UI 组件类型,grid组件
data-columns="[ //行列内容设置
{ field: 'name',//this.dataSource中name属性对应的值
title: '名字',//列名称
width:150, //列表宽
attributes:{ //列样式设置
class:'table-cell', //设置css样式
style:'text-align:right; font-size:18px'//设置属性
}
},
{ field: 'bz', //this.dataSource中bz属性对应的值
title: '备注',
width:200
}
]"
data-bind="source:dataSource" //对应数据源
style="height:300px; margin-top:10px;"
id="grid" />
columns复合标题头
columns: 标题列组合,并且支持标题列多层合并显示。
<div data-role="grid" // UI 组件类型,grid组件
data-columns="[
{//第一个标题组
title: '基础信息',
columns: [
{ field: 'name', title:'名称' },//列标题与数据源属性对应关系
{ field:'age', title:'年龄' }//列标题与数据源属性对应关系
]
},
{//第二个标题组
title: '其他信息',
columns: [
{ field: 'bz', title:'备注' },//列标题与数据源属性对应关系
{ field: 'ct', title:'城市' }//列标题与数据源属性对应关系
]
},
{
field: 'pho', title: '电话'
}
]"
data-bind="source:dataSource" //引入数据源
style="height:150px; margin-top:10px;"
id="grid1" />
command编辑列
**command:**行编辑标记设置。自定义的或内置的(“修改”或“删除”)。多数情况我们不会使用自带的修改与删除功能。
内置“ edit”命令可在编辑模式下切换当前表行。
内置命令“ destroy”将删除当前表行绑定到的数据项。
<div data-role="grid" // UI 组件类型,grid组件
data-columns="[
{ field: 'name',//this.dataSource中name属性对应的值
title: '名字',//列名称
width:150
},
{ field: 'bz', //this.dataSource中bz属性对应的值
title: '备注',
width:200
},
{ command: ['edit', 'destroy'] }//启用行标记模式
]" |
data-bind="source:dataSource" |
data-editable='inline', //设置行为数据编辑模式
style="height:150px; margin-top:10px;"
id="grid2" />
command.click编辑列事件
command.click: 自定义行列中的按钮事件,在项目开发中经常使用到。
<div data-role="grid" // UI 组件类型,grid组件
data-columns="[{
field: 'name',//this.dataSource中name属性对应的值
title: '名字',//列名称
width:150
},
{ field: 'bz', //this.dataSource中bz属性对应的值
title: '备注',
width:200
},
{ command: [{ //行里编辑模式
name: '事件点击', //按钮名称
click: function(e) {
// e.target 获得事件类对应行的DOM元素
var tr = $(e.target).closest('tr'); //获得表中tr数据 (tr)
// 获得tr数据中的行数据信息
var data = this.dataItem(tr);
alert(data.name);//获得行数据中的name属性数据
}
}]
}
]"
data-bind="source:dataSource"
data-editable='inline',
style="height:150px; margin-top:10px;"
id="grid3" />
command编辑列样式
command其他属性: 行列编辑模式下可以加入其他数据
- className 按钮css样式引入
data-columns="[
{ field:'name',title: '名字'},
{ command: [ //行编辑列设置
{ className: "btn-destroy" //css样式引入
, name: "按钮名称"
}] }
]"
- iconClass 按钮图标设置
data-columns="[
{ field:'name',title: '名字' },
{ command: [{
name: '修改保存',
iconClass: 'k-icon k-i-copy' //图标名称
}]
}]"
command template编辑列模板
- template 编辑中加入模板功能
{ title: '模板模式',
command: [{
name: 'update',----------------------------------------------------------
//模板定义模板名字与 a元素中的class中 k-button k-grid-模板名称 对应成为按钮 |
template: '这是模板<a class=\'k-button k-grid-update\'>
<span class=\'k-icon k-i-settings\'></span>模板字符</a>',
//小技巧 js 中 \' 在字符串中表示'的转义字符
click(e){//事件
kendo.alert('Settings clicked!');
}
}]
}
template基础列模板
template模板自定义列内容: 开发者自定义表格行列中的html内容。
-
基础模板 在列设置中定义template属性,属性内容是自定义列的内容,引入的变量默认是列的 field:名称。
模板显示变量的时候需要使用模板语法显示,#=属性名称# 或者 #:属性名称# 才可以引入。
<div data-role="grid" // UI 组件类型,grid组件
data-columns="[
{ field: 'name',//this.dataSource中name属性对应的值
title: '名字',//列名称
width:150
},
{ field: 'bz', -------------- //this.dataSource中bz属性对应的值
title: '自定义测试', |
width:200, | 模板中的bz引用名称 是field中定义的
template: '我是模板<strong>#=bz# </strong>'//模板定义
},
]"
data-bind="source:dataSource"
style="height:150px; margin-top:10px;"
id="grid4"></div>
-
kendo.template 模板函数
kendo.template($(’#模板名称’).html()) 使用kendo自带的共通函数
如果开发遇到复制的业务时候,通常会使用到模板函数这个功能开进行复杂的业务逻辑处理。
-
模板语法
在kendo模板中为与数据模型中的数据进行交换赋值需要使用kendo自带的模板语法,语法#: 变量 引用#这样获得数据内容。
js脚本定义 两个#好中包含脚本 #if(bz==null){# 中定义js原生语法来进行脚本操作。
<div data-role="grid" // UI 组件类型,grid组件
data-columns="[
{ field: 'name',//this.dataSource中name属性对应的值
title: '名字',//列名称
width:150
},
{ field: 'bz', //this.dataSource中bz属性对应的值
title: '自定义测试',
width:200,
template: '我是模板<strong>#=bz# </strong>'
},
{ field: 'bz', //this.dataSource中bz属性对应的值
title: '模板函数',
width:200,
template:kendo.template($('#name-template').html())
}, |
]" |
data-bind="source:dataSource" | 引入模板名称
style="height:150px; margin-top:10px;" |
id="grid4"></div> |
| ----------------------------------------|
<script id="name-template" type="text/x-kendo-template">
{{name}} //引入全局参数名称
<strong>#: bz #</strong> //引入列参数名称
#if(bz==null){# //模板判断语法
这个数据是空 //
#}else if(bz!=null){# //模板判断语法
没有空数据
#}#
</script>
-
template function(dataItem) 函数模板
自定义函数定义html内容,function(dataItem) dataItem参数为行中所有数据内容。
<div data-role="grid" // UI 组件类型,grid组件
data-columns="[
{ field: 'name',//this.dataSource中name属性对应的值
title: '名字',//列名称
width:150
},
{
title: '自定义函数',
width:150,
template: function(dataItem) {//函数模板定义
//返回列的html内容
return '<strong>' + kendo.htmlEncode(dataItem.name)+kendo.htmlEncode(dataItem.bz) + '</strong>';
}
},
]"
data-bind="source:dataSource"
style="height:150px; margin-top:10px;"
id="grid4"></div>
- template function(dataItem) 函数与kendo.template 模板混合使用
在函数体中引入模板函数
var template= kendo.template($(’#name-template-add’).html());
var result = template(dataItem);
return result;
<div data-role="grid" // UI 组件类型,grid组件
data-columns="[
{ field: 'name',//this.dataSource中name属性对应的值
title: '名字',//列名称
width:150
},
{
title: '自定义函数',
width:150,
template: function(dataItem) { //定义函数
//创建模板对象,name-template-add 模板对象引用
var template= kendo.template($('#name-template-add').html());
//将行数据对象传给模板对象,生产html字符串
var result = template(dataItem);
return result;//返回html字符串
}
},
]"
data-bind="source:dataSource"
style="height:150px; margin-top:10px;"
id="grid4"></div>
<script id="name-template-add" type="text/x-kendo-template">
<strong>#:name # 和 #:bz #</strong>
</script>
format列格式
**format 列格式:**用于设置列的特殊参数格式,常常用于时间格式。{0: yyyy-MM-dd HH:mm:ss}
this.dataSource=new kendo.data.DataSource({data:[
{name:'z1',age:12,'bz':'备注1',ct:'鞍山',pho:'123232', date: new Date(), number: 23.4433},
{name:'z2',age:1333,'bz':'看我',ct:'鞍山',pho:'1232', date: new Date(), number: 123.2342},
{name:'z3',age:1333,'bz':'我啦啦',ct:'沈阳',pho:'1232', date: new Date(), number: 3.00}
]});//创建一个数据源
<div data-role="grid" // UI 组件类型,grid组件
data-columns="[
{
title: '数字',
field: 'number',
format: '{0:c}',//数值格式
width:150
},
{ field: 'date',//this.dataSource中bz属性对应的值
title: '时间',
format:'{0: yyyy-MM-dd HH:mm:ss}',//时间格式
width:200
}
]"
data-bind="source:dataSource"
data-editable='inline',
style="height:150px; margin-top:10px;"
id="grid5" /></div>
locked 列冻结
**locked 行列冻结功能:**表格中对列宽进行锁定。
data-columns="[
{
title: '数字',
field: 'number',
format: '{0:c}',
locked: true,//锁定这个列
width:450
},
{ field: 'date', //this.dataSource中bz属性对应的值
title: '时间',
format:'{0: yyyy-MM-dd HH:mm:ss}',
width:900
}
]"
sticky列联动
sticky 列宽联动: 列表格与宽进行联动
data-columns="[
{
title: '数字',
field: 'number',
format: '{0:c}',
sticky:true, //设置成带宽联动
width:450
}
]"
Grid UI 模板基本配置属性
griid组件是kendo UI中我们经常使用到的重要组件,以下将介绍 griid组件中常常用到的基础属性,掌握这些属性可以更好的开发出符合业务要求的表格。
属性名称 | hbs中属性 | 介绍 |
---|---|---|
role | data-role | 代表组件类型 |
selectable | data-selectable | 表格是否可编辑类型设置 |
autobind | data-auto-bind | 数据初始化 |
sortable | data-sortable | 单击列标题对表格进行排序 |
resizable | data-resizable | 调整列宽大小 |
editable | data-editable | 行数据编辑模式 |
scrollable | data-scrollable | 显示滚动条 |
pageable | data-pageable | 分页设置功能 |
data-bind | DataSource 数据源绑定与事件绑定,参数绑定。 | |
height | data-height | 设置表格高度 |
width | data-width | 设置表格宽度 |
columns | data-columns | 设置表行列基础内容 |
**data-role:**代表组件类型 grid 表格类型。例如:data-role=“grid”
data-selectable:表格是否可以编辑状态。 例如:data-selectable=“multiple,row”
- “row” - 可以选择单个行。
- “cell” - 可以选择一个单元格。
- “multiple, row” -可以选择多行。
- “multiple, cell” - 可以选择多个单元格。
**data-auto-bind:**初始化参数为true,绑定数据源执行DataSource 中的read()方法。设置为false时候不会执行数据源read()方法,需要事件触发read()方法。
例如:data-auto-bind=“true” 初始化时加载DataSource 中的read()方法。
- “true” 初始化数据
- “false”不初始化数据
**data-sortable:**可以通过单击列标题对表格进行排序。true排序,fales不排序
**data-resizable:**通过拖动列标题单元格的边缘(调整大小列宽)来调整列的大小。
例如: data-resizable=“true” 可以调整大小
- “true” 可以调整大小
- “false”不可以调整大小
**data-editable:**将选择行数据保存到编辑组件页面中。data-editable=“popup” 弹出修改框。分为(“ inline”,“ incell”或“ popup”)三种模式
-
“ inline”
-
“ incell”
-
“ popup”
**data-scrollable:**则当总行高(或宽度)超过表格定义的高度(或宽度)时,将显示滚动条。默认初始值为true。true出现滚动条,false溢出滚动条。
**data-pageable:**默认情况下,禁用分页。分页设置需要以json形式,在json对象中设置分页的属性参数。通过参数来定义自己的分页样式。例如:{ pageSizes: [10, 50, 100], pageSize: 10}
<div data-role="grid"
data-pageable="{ //分页设置
pageSize:10,
pageSizes:[10,20,50]
}"
//表行列与数据源内容对应关系,列的基本属性设置
data-columns="[
{ field: 'name', title: '名字', width:150 },
{ field: 'age', title: '数字', width:100 },
{ field: 'bz', title: '备注', width:200 },
{ command: 'edit',width:100 }
]" data-bind="source:dataSource"
id="grid">
-
pageSize:设置分页行数,例如pageSize:2 两行记录分为一页。
如果为表格分配一个已经存在的 DataSource实例,这个设置将不起作用。需要在DataSource 实例中设置分页参数。
// 数据源中设置分页参数 this.dataSource=new kendo.data.DataSource({data:[ {name:'z1','age':12,'bz':'备注一'}, {name:'z2','age':12,'bz':'备注2'}, {name:'z3','age':14,'bz':'备注2'}, {name:'z4','age':15,'bz':'备注3'}, {name:'z5','age':17,'bz':'备注4'}, {name:'z6','age':17,'bz':'备注5'}, {name:'z7','age':17,'bz':'备注6'}, {name:'z8','age':17,'bz':'备注7'}, {name:'z9','age':17,'bz':'备注8'} ],pageSize:2 //DataSource实例化后如果需要分页,设置pageSize属性进行分页 }); | | <div data-role="grid" | data-pageable="{ | pageSize:2 // 注意重点。。。。。在这设置分页是无效的 }" //表行列与数据源内容对应关系,列的基本属性设置 data-columns="[ { field: 'name', title: '名字', width:150 }, { field: 'age', title: '数字', width:100 }, { field: 'bz', title: '备注', width:200 }, { command: 'edit',width:100 } //绑定DataSource实例对象dataSource ]" data-bind="source:dataSource" style="height:200px; margin-top:10px;" id="grid">
-
pageSizes: 分页行数下拉菜单设置,允许用户选择页面行数动态生成每页对应的分页行数。
例如 pageSizes:[5,10,20] 设置为5行,10行,20行分页。pageSizes: [2, 3, 4, “all”],all所有行数。
-
alwaysVisible: 设置为分页总数,总数小于分页数时隐藏分页组件。alwaysVisible:fales (隐藏)
pageSize=10时当前行数是8 不出现分页组件。
-
info: 当前页面和数据项总数的信息,默认true。false不显示 例如:info:false 条数总页数不显示。
-
input: 分页数输入框元素显示。用户可以在输入框中设置自己想分页的页数,默认是false。
例如:input:true 显示。
-
refresh:显示刷新按钮 ,默认值:false。
-
position: 分页组件显示位子。“ top”(头部)和“ bottom”(底部默认)。
例如 position: "top"或者 position: “bottom”。
data-height : 设置表格高度。 例如: data-height=“300” //高度为300px
data-width: 设置表格宽度。 例如:data-width=“700” //宽度为300px
表格示例代码
<div data-role="grid" // UI 组件类型,grid组件
data-selectable="multiple,row" // 组件编辑状态
data-auto-bind="true" // 组件初始化加载
data-editable="popup" //弹出框模式
data-resizable="true" //单元格列宽大小设置
data-pageable="{
//分页数设置 如果定义了DataSource实例,需要在DataSource实例中定义这个属性
pageSize:2,
//分页行数下拉菜单设置(2行,5行,10行,20行)
pageSizes:[2,5,10,20],
//实际小于分页行数,隐藏分页组件
alwaysVisible:true,
//显示页面和数据项总数的信息(false不显示)
info:true,
refresh:true,//刷新按钮显示
position:'bottom' //显示组件位子
}"
//表行列与数据源内容对应关系,列的基本属性设置
data-columns="[
{ field: 'name', title: '名字', width:150 },
{ field: 'bz', title: '备注', width:200 },
{ command: 'edit' } //加上编辑功能
//绑定DataSource实例对象dataSource
]" data-bind="source:dataSource"
class="customGrid" //css样式设置
//表格样式设置 如果不想使用style设置高与宽。
//。可以说使用 data-height="300" data-width="700"
style="height:300px; margin-top:10px;"
id="grid">
</div>
MVVM 模板下使用data-bind绑定数据源与事件(例子4)
Kendo 在mvvm模式下,对HTML页面的操作使用的是模板导入技术,本质上是在模板中的字符串中对HTML元素进行操作。这样都导致我们不能像在原生html页面中一样操作和控制元素中的 js对象,事件方法等等其他html功能,所有我们要使用到kendo.bind方法的将模板中的HTML元素与js中的对象,方法,数据,属性进行关联。
-
data-bind: 在模板对象使用这个元素来加载数据源,事件方法等功能。
data-bind方法的原型是kendo.bind 函数。例如 kendo.bind($(“select”), viewModel);
grid组件常用的到的绑定属性有:source,selected,events这三个属性。
data-bind 例子
<div data-role="grid" data-selectable="multiple,row" data-columns="[ { field: 'name', title: '名字', width:150 }, { field: 'bz', title: '备注', width:200 }, { command: 'edit' } //加上编辑功能 ]" data-editable="popup" //通过模板data-bind方法,将ViewModel逻辑类中的数据源信息绑定给模板元素。 // source:dataSource grid组件中的source属性对应 dataSource 数据源 data-bind="source:dataSource" style="height:300px; margin-top:10px;" id="grid"></div>
bind绑定方法
属性 | 名称 | 内容 |
---|---|---|
Source and template binding | **source ** | 数据源信息对应模板中组件 |
grid selected | selected | 获得点击获得编辑行数据信息 |
events{} | events | 添加组件接口信息内容 |
data-bind=selected:行数据: 必备条件是kendo grid组件必须是 data-selectable=“multiple,row” 行列数据可编辑的模式下才可以使用这个属性。
- ViewModel 在逻辑类中定义 kendo.data.Model[] 的_sits 对象,用这个Model对象在模板中的data-bind=selected:sits 进行绑定。
- _sits: kendo.data.Model[] = [] 因为在页面中用户可能选择多个编辑行,这写编辑行保存在Model[]数组中。
ViewModel.ts(逻辑类)
--------------------------------------------------------------------------------
export default class ViewModel extends kendo.data.ObservableObject {
public dataSource: kendo.data.DataSource;//创建数据源引用
protected _sits: kendo.data.Model[] = [];//创建编辑行数据信息,[]数组是页面选择多行编辑
//构造函数 |
constructor() { |
super(); |
this.dataSource=new kendo.data.DataSource({data:[ |
{name:'z1','age':12,'bz':'备注1'}, |
{name:'z2','age':1333,'bz':'备注2'}, |
{name:'z3','age':1333,'bz':'备注3'}, |
]});//创建一个数据源 |
} |
//查看是否获得到编辑行数据内容 |
public _onSitsfind():void{ |
//this.sitsItems[0]获得选择的第一行数据内容 |
alert(this.sitsItems[0].get('name')); |
} |
//编辑行数据信息get set方法封装。面向对象编程 |
get sitsItems(): kendo.data.Model[] { |
return this.get('_sits'); |
} |
set sitsItems(selected: kendo.data.Model[]) { |
this.set('_sits', selected); |
} |
} |
ViewModel.ts(逻辑类) |
--------------------------------------------------------------------------- | <button type="button" data-bind="click:_onSitsfind">selected获得行数据</button> |
<div data-role="grid" |
data-selectable="multiple,row" //必须设置为可编辑 |
data-columns="[ |
{ field: 'name', title: '名字', width:150 }, |
{ field: 'bz', title: '备注', width:200 }, |
{ command: 'edit' } //加上编辑功能 |
]" |
data-editable="popup" |
data-bind="source:dataSource,selected:_sits"
//设置为点击行(变色)获得行数据
style="height:300px; margin-top:10px;"
id="grid"></div>
事件绑定data-bind=events:{change:grid_change}: 模板中的组件事件与逻辑类中的方法进行绑定。
- 在ViewModel 逻辑类中定义事件触发方法。在方法中编写需要完成的业务逻辑代码。
- data-selectable=“multiple,row” 或者 data-selectable=true 表为编辑模式。
- Event e 事件中e.sender.select() 选择事件索引。
- data-selectable=“multiple,row” 模式下grid组件的事件才会被触发。
ViewModel.ts(模板)
---------------------------------------------------------------------
export default class ViewModel extends kendo.data.ObservableObject {
public dataSource: kendo.data.DataSource;//创建数据源引用
protected _sits: kendo.data.Model[] = [];
protected _userItem!: kendo.data.Model;//定义kendo 数据模型基础类
//构造函数
constructor() {
super();
this.dataSource=new kendo.data.DataSource({data:[
{name:'z1','age':12,'bz':'2222'},
{name:'z2','age':1333,'bz':'2222'},
{name:'z3','age':1333,'bz':'2222'},
]});//创建一个数据源
}
public grid_change(e:any):void{ //定义grid点击选择事件方法 <---------|
// e.sender.select() 获得选择的行索引 |
// e.sender.dataItem(e.sender.select())获得行数据信息 |
console.log(e.sender.dataItem(e.sender.select()).get('name')); |
console.log(e); |
//行数装入到逻辑类自定义的属性中。 | this.set('selectedRow',e.sender.dataItem(e.sender.select())); |
//this._userItem 获得行选择中的行数据 |
this._userItem=e.sender.dataItem(e.sender.select()); |
} |
} |
template.ts(模板) |
--------------------------------------------------------------------- |
<div data-role="grid" |
data-selectable="multiple,row"//必须点击编辑事件必须为表格可编辑模式 |
data-columns="[ |
{ field: 'name', title: '名字', width:150 }, |
{ field: 'bz', title: '备注', width:200 } |
]" |
data-editable="popup" |
data-bind="source:dataSource,events:{change:grid_change}" <-|
style="height:300px; margin-top:10px;"
id="grid1"></div>
grid 组件常用事件
事件名称 | 作用 | 备注 |
---|---|---|
change | 选择表的行或者列的时候触发 | data-selectable=“multiple,row” 触发事件 |
edit | 当编辑或创建表的数据是触发 | 表为编辑模式 |
dataBinding | 绑定数据源之前触发 | |
page | 分页器改变当前索引时触发 | e.page页面索引 |
export default class ViewModel extends kendo.data.ObservableObject {
public dataSource: kendo.data.DataSource;//创建数据源引用
protected _sits: kendo.data.Model[] = [];
protected _userItem!: kendo.data.Model;//定义kendo 数据模型基础类
//构造函数
constructor() {
super();
this.dataSource=new kendo.data.DataSource({data:[
{name:'z1','age':12,'bz':'2222'},
{name:'z2','age':1333,'bz':'2222'},
{name:'z3','age':1333,'bz':'2222'},
]});//创建一个数据源
}
public grid_page(e:any):void{
alert(e.page);//获得页面索引
}
}
<div data-role="grid"
data-selectable="multiple,row"//必须点击编辑事件必须为表格可编辑模式
data-columns="[
{ field: 'name', title: '名字', width:150 },
{ field: 'bz', title: '备注', width:200 }
]"
data-editable="popup"
data-bind="source:dataSource,events:{page:grid_page}"
style="height:300px; margin-top:10px;"
id="grid1"></div>
grid 常用方法
名称 | 作用 | 例子 |
---|---|---|
items | 获取grid组件中DOM元素的数组 | var grid = $("#grid").data(“kendoGrid”); var allRows = grid.items(); grid.select(allRows); |
cellIndex | 返回指定行中列的索引 | var grid = $("#grid").data(“kendoGrid”); console.log(grid.cellIndex(“td:eq(1)”)); |
editCell | 将行列设置为编辑模式 | var grid = $("#grid").data(“kendoGrid”); grid.editCell( ("#grid td:eq(0)") ); |
getOptions | 获得行编辑状态数据 | var grid = $("#grid").data(“kendoGrid”); var options = grid.getOptions(); console.log(options.sortable); var obj= kendo.stringify(options.columns); |
select | 获得所有编辑状态行 | var grid = $("#grid").data(“kendoGrid”); grid.select(“tr:eq(0), tr:eq(1)”); |
addRow | 添加行 | |
editRow | 编辑行 | |
removeRow | 删除行 | var grid = $("#grid").data(“kendoGrid”); grid.removeRow(“tr:eq(2)”); |
解决grid 编辑列模式下模板套模板无法和逻辑类交互
在使用过一段kendo mvvm模式开发后发现一个问题,就是在template模板中如果grid 列表组件中的列为模板模式,在列中自定义的template模板,里面的所有html元素都无法使用data-bind绑定 ViewModel.ts 逻辑类中的事件与数据。
这个问题的原因就是kendo mvvm模式中template.hbs 模板与 ViewModel.ts 逻辑类的绑定方式,kendo new kendo.View在绑定的时候只对第一层的模板绑定,不会对模板下一层的子模板进行绑定。
在传统模式中绑定方式
<div id="grid"></div>
<script id="template" type="text/x-kendo-template">
<a class="k-button" href="\#" onclick="return toolbar_click()">Command</a>
</script>
<script>
function toolbar_click() {
console.log("Toolbar command is clicked!");
return false;
}
$("#grid").kendoGrid({
toolbar: [
{ template: kendo.template($("#template").html()) }
],
columns: [
{ field: "name" },
{ field: "age" }
],
dataSource: [
{ name: "Jane Doe", age: 30 },
{ name: "John Doe", age: 33 }
]
});
</script>
编辑列中template(模板) 的绑定事件toolbar_click 与function toolbar_click() 方法都是在一个html页面中的doucment下面。所以可以很方便的将模板中的事件与script 中的方法绑定。
但是在MVVM 模式下无法使用这种模式进行模板事件和逻辑类中的方法进行绑定。原因是子模板在 MVVM kendo框架中没有给他提供对应的绑定接口,将子模板与业务逻辑类中的方法绑定到一起。
框架之提供了 const view = new kendo.View(template,{model:ViewModel}); 在indext.ts类中主模板与业务逻辑类的绑定,它们没有对子模板进行绑定。
例如:这个 name-template子模板绑定事件 data-bind=“click:_onSitsfind” 是无效的。
<div data-role="grid"
data-selectable="multiple,row"
data-columns="[
{ field: 'name', title: '名字', width:150 },
{ field: 'bz', title: '备注', width:200 },
{ title: '模板模式',
command: [{
name: 'update',
template:kendo.template($('#name-template').html())
}]
}
]"
data-editable="popup"
data-bind="source:dataSource,
events:{change:grid_change}"
style="height:300px; margin-top:10px;"
id="grid1"></div>
</div>
<script id="name-template" type="text/x-kendo-template">
//data-bind="click:_onSitsfind"
//这个绑定事无效,是无法与ViewModel.ts 方法进行绑定的
<button type="button" data-bind="click:_onSitsfind">
修改信息
</button>
</script>
怎么解决这个问题呢,好在MVVM 模式是单页模式,我们定义一个能绑定逻辑类的元素作为缓存元素,用模板中方法与这个中间缓存元素进行通信来达到与逻辑类方法和数据进行通信。
ViewModel.ts(业务逻辑)
---------------------------------------------------------------------
export default class ViewModel extends kendo.data.ObservableObject {
public dataSource: kendo.data.DataSource;//创建数据源引用
protected _sits: kendo.data.Model[] = [];
protected _userItem!: kendo.data.Model;//定义获得grid行数据的数据结构与类型
//构造函数
constructor() {
super();
this.dataSource=new kendo.data.DataSource({data:[
{name:'z1','age':12,'bz':'2222'},
{name:'z2','age':1333,'bz':'2222'},
{name:'z3','age':1333,'bz':'2222'},
]});//创建一个数据源
}
//缓存元素的绑定方法
public clickEit():void {
const $el=$('#budzht');//获得模板中缓存元素
//alert($el.data().zhtbs.name); $el.data().zhtbs
//通过名称将缓存中的行数据拿出。 $el.data().zhtbs
//赋值给 this._userItem ,可以在中模板将_userItem与其他业务元素绑定达到数据互动的效果
this._userItem=$el.data().zhtbs;
alert(this._userItem.get('name'));
}
}
template.ts(模板)
---------------------------------------------------------------------
<div data-role="grid"
data-columns="[
{ field: 'name', title: '名字', width:150 },
{template:kendo.template($('#name-template').html()),
title: '备注', width:200 },
{ title: '模板模式',
command: [{
name: 'update',
template: '这是模板a class=\'k-button k-grid-update\' >修改内容</a>',
click(e){ //编辑行触发事件
// 通过事件源,获得事件触发行的数据
var tr = $(e.target).closest('tr');
// 在列表数组中获得这个行的数据信息
var data = this.dataItem(tr);
var $el = $('#budzht');
$el.data('zhtbs', data);//使用jquery将行数据绑定在元素dom节点中
$('#budzht').click();//执行ViewModel.ts中的事件
}
}]
}
]"
data-editable="popup"
data-bind="source:dataSource,events:{click:clicktxt}"
style="height:300px; margin-top:10px;"
id="grid2"></div>
<button type="button"
data-bind="click:clicktxt" // ViewModel.ts中的方法
id="budzht"
style="display:none">表行与逻辑类中间通行元素</button>
- 1 在grid组件中,行columns设置中定义编辑列command
- 2 定义编辑列的事件click。
- 3 在编辑列的事件中获得行数据,并保存在缓存元素缓存中,触发缓存元素的方法。
- 4 定义一个中间缓存元素 ,中间缓存元素事件data-bind 与ViewModel.ts 方法绑定。
- 5 在ViewModel.ts的方法中将缓存元素中的行数据拿出来。
第四章 FROM表单
在kendo mvvm 表单中需要学习如何在逻辑类中建立表单的数据模型,在将数据模型与模板中的from 数据进行绑定。
MVVM 表单绑定ViewModel (例子5)
我们使用的kendo MVVM模式与表单数据进行关联。我们使用了JAVA 面向对象模式进行开发绑定,在javaScript中仅创建模型对象通过kendo 函数将表单中的DOM 与javaScript模型进行对应,达到联动的效果。通过控制javaScript数据模型就可以对表单数据修改获得等操作。
1 创建 Model Kendo 数据模型
1 创建kendo.data.Model 类型数据对象,用于和表单数据进行交互绑定。同时也是 DataSource 数据源绑定数据类型。
const MainModel = kendo.data.Model.define({//定义类型,定义这个json为 kendo 的 Model类型
id: 'id',
fields: { //editable:是否可编辑 false不可编辑
id: { type: 'string',
editable: false, nullable: true}//定义数据项的属性内容
},
});
export {MainModel};//引包对象设置
Mokel类的常用方法
- define
Model类型的创建kendo.data.Model.define({内容});
- editable
是否字段属性是否可编辑的。
-
isNew
检查
Model
是否是新创建的。通过id
字段来判断模型数据新与旧。id字段是在fields
配置指定的默认值。 -
toJSON
JavaScript对象转换。
var observable = new kendo.data .ObservableObject({ person: { name: "John Doe" } }); var json = observable.toJSON(); console.log(JSON.stringify(json)); // outputs {"person":{"name":"John Doe"}}
2 Model 数据模型在ViewModel类中定义
ViewModel.ts(业务逻辑)
---------------------------------------------------------------------
import { MainModel } from './Model';//引入创建的数据模型与表单数据绑定用
export default class ViewModel extends kendo.data.ObservableObject {
public dataSource: kendo.data.DataSource;//创建数据源引用
protected _userItem!: kendo.data.Model;//定义数据表单绑定的属性引用
//构造函数
constructor() {
super();
this.dataSource=new kendo.data.DataSource({data:[
{name:'z1','age':12,'bz':'2222'},
{name:'z2','age':1333,'bz':'2222'},
]});//创建一个数据源
this.getUser=new MainModel();//_userItem 在创造函数中初始化这个引用对象
} |
//表单属性引用 封装为getUser()方法名称 |
get getUser(): kendo.data.Model{ |
return this.get('_userItem');//绑定对象 <----------- |
} |
set getUser(user:kendo.data.Model){ |
this.set('_userItem',user); |
} |
} |
template.ts(模板) |
------------------------------------------------------ |
<label for="">名称:</label> | //绑定方式
<input data-role="text" name="name"
data-bind="value:getUser.name" />
<label for="">数字:</label>
<input data-role="numerictextbox" name="age"
data-bind="value:getUser.age"/>
<label for="">备注:</label>
<textarea data-role="textarea" name="bz"
data-bind="value:getUser.bz" />
<button data-role="button" type="button"
data-bind="click:onSave,enabled:isButtonSave" id="zht">提交信息</button>
<button data-role="button" type="button"
data-bind="click:onUpdate,enabled:isButtonUp" id="zht">修改</button>
-
1 定义一个与HTML表单绑定的属性引用protected _userItem!: kendo.data.Model。
-
2 创建这个引用的方法引用,为了符合面向对象编程的语言。像java中的pojo类的,get和set方法.
-
3 在创造函数中初始化这个引用对象。
-
4 在 template.ts(模板)中绑定html表单元素。data-bind=“value:getUser.name”
3 表单数据与grid列表联动
在很多时候为了方便开发,html中的表单提交都需要与grid表单进行联动操作。我们只需调用dataSource引用,使用dataSource提供的方法,就可以达到与引用dataSource的kendo组件进行联动操作的功能。
this.dataSource.add(this.getUser);将新添加数据添加到数据源引用中来。
ViewModel.ts(业务逻辑)
---------------------------------------------------------------------
import { MainModel } from './Model';//引入创建的数据模型与表单数据绑定用
public dataSource: kendo.data.DataSource;//创建数据源引用
protected _userItem!: kendo.data.Model;
//构造函数
constructor() {
super();
this.dataSource=new kendo.data.DataSource({data:[
{name:'z1','age':12,'bz':'2222'},
{name:'z2','age':1333,'bz':'2222'},
{name:'z3','age':1333,'bz':'2222'},
]});//创建一个数据源
this.getUser=new MainModel();//数据初始化
}
//创建一个添加方法保存表单绑定的数据写入
public onSave():void{
this.dataSource.add(this.getUser);
this.getUser=new MainModel();
}
//表单数据和行数据 Model类
get getUser(): kendo.data.Model{
return this.get('_userItem');
}
set getUser(user:kendo.data.Model){
this.set('_userItem',user);
}
}
template.ts(模板)
------------------------------------------------------
<label for="">名称:</label>
<input data-role="text" name="name"
data-bind="value:getUser.name" />
<label for="">数字:</label>
<input data-role="numerictextbox" name="age"
data-bind="value:getUser.age"/>
<label for="">备注:</label>
<textarea data-role="textarea" name="bz"
data-bind="value:getUser.bz" />
<button data-role="button" type="button"
data-bind="click:onSave,enabled:isButtonSave"
id="zht">提交信息</button>
<button data-role="button" type="button"
data-bind="click:onUpdate,enabled:isButtonUp"
id="zht">修改</button>
<div data-role="grid"
data-selectable="multiple,row"
data-columns="[
{ field: 'name', title: '名字', width:150 },
{ field: 'age', title: '数字', width:200 },
{ field: 'bz', title: '备注', width:200 },
]"
data-editable="popup"
data-bind="source:dataSource,selected:_sits,events:{change:grid_change}"
style="height:300px; margin-top:10px;"
id="grid"></div>
2 添加与修改的例子,FROM表单中按钮显示与隐藏功能设置
const MainModel = kendo.data.Model.define({
id: 'id',
fields: {
id: { type: 'string', editable: false, nullable: true}
},
});
export { MainModel};
ViewModel.ts(业务逻辑)
---------------------------------------------------------------------
import { MainModel } from './Model';
export default class ViewModel extends kendo.data.ObservableObject {
public dataSource: kendo.data.DataSource;//创建数据源引用
protected _sits: kendo.data.Model[] = [];
protected _userItem!: kendo.data.Model;
//构造函数
constructor() {
super();
this.dataSource=new kendo.data.DataSource({data:[
{name:'z1','age':12,'bz':'2222'},
{name:'z2','age':1333,'bz':'2222'},
{name:'z3','age':1333,'bz':'2222'},
]});//创建一个数据源
this.getUser=new MainModel();//数据初始化
}
public onSave():void{
this.dataSource.add(this.getUser);
this.getUser=new MainModel();//添加成功后重新创建一个引用
this.isUp(false);
}
public onUpdate():void{
this.isUp(false);
this.getUser=new MainModel();//修改成功后重新创建一个引用
}
//列表的点击选择事件
public grid_change():void{
this.getUser=this.sitsItems[0];
this.isUp(true);
}
//编辑grid组件行数据信息get set方法封装。面向对象编程
get sitsItems(): kendo.data.Model[] {
return this.get('_sits');
}
set sitsItems(selected: kendo.data.Model[]) {
this.set('_sits', selected);
}
//表单数据和行数据 Model类
get getUser(): kendo.data.Model{
return this.get('_userItem');
}
set getUser(user:kendo.data.Model){
this.set('_userItem',user);
}
public isUp(is:boolean):void{
this.set('isupflag',is);
}
//修改按钮显示与隐藏功能
public isButtonUp():boolean{
const isflag=this.get('isupflag');
if(isflag==''){
return false;
}
if(isflag==undefined){
return false;
}
return isflag;
}
//添加按钮显示与隐藏功能
public isButtonSave():boolean{
const isflag=this.get('isupflag');
if(isflag==''){
return true;
}
if(isflag==undefined){
return true;
}
return !isflag;
}
}
template.ts(模板)
------------------------------------------------------
<label for="">名称:</label>
<input data-role="text" name="name"
data-bind="value:getUser.name" />
<label for="">数字:</label>
<input data-role="numerictextbox" name="age"
data-bind="value:getUser.age"/>
<label for="">备注:</label>
<textarea data-role="textarea" name="bz"
data-bind="value:getUser.bz" />
//click 添加事件 enabled 添加按钮可用与不可用事件
<button data-role="button" type="button"
data-bind="click:onSave,enabled:isButtonSave"
id="zht">提交信息</button>
<button data-role="button" type="button"
data-bind="click:onUpdate,enabled:isButtonUp"
id="zht">修改</button>
<div data-role="grid"
data-selectable="multiple,row"
data-columns="[
{ field: 'name', title: '名字', width:150 },
{ field: 'age', title: '数字', width:200 },
{ field: 'bz', title: '备注', width:200 },
]"
data-editable="popup"
data-bind="source:dataSource,selected:_sits,events:{change:grid_change}"
style="height:300px; margin-top:10px;"
id="grid"></div>
表单验证validate与格式 (例子6)
表单验证用户输入的数据是所有项目的重要任务之一,Kendo使用的主要自带验证规则类型有以下几种,输入字段可具有类型,例如URL
,NUMBER
,RANGE
,DATE
,SEARCH
,和COLOR
。除了类型之外,还可以通过向required
输入元素添加其他属性来标记表单元素。
例如,可以将仅接受电子邮件地址的输入字段指定为type=email
。
kendo验证基础是HTML5功能的验证,如果用户的浏览器是某些旧的版本浏览器或者不支持HTML5功能。那么这些验证功能都将全部无效。
//required 必填项目
//validationMessage="名字不能为空"
//pattern="\d{3}" 正则验证
//data-pattern-msg="请录入数字"
<form id="testView">//验证form信息内容
<div>
<label for="name">名称不为空:</label>
<input data-role="text" name="name"
required
validationMessage="名字不能为空"
data-bind="value:getUser.name" />
</div>
<div>
<label for="money">数字:</label>
<input
type="text"
pattern="\d{3}"
data-bind="value:getUser.money"
data-pattern-msg="请录入数字"
name="money" id="money" />
</div>
<div data-container-for="" class="k-edit-field">
<button data-role="button"
type="button"
data-bind="click:onSave" >提交信息验证</button>
</div>
</form>
export default class ViewModel extends kendo.data.ObservableObject {
public onSave():void{
//验证testView 信息内容
const validator = $('#testView').kendoValidator().data('kendoValidator');
alert(validator.validate());
}
}
定义Validator
在模板中template.hbs中的定义一个form元素,在form元素中写所有需要判断html表单内容。
<form id="testView">
表单内容
</form>
在逻辑类的脚本中引用这个form元素,使用kendo方法进行验证。通过判断验证是否通过,在进行下一步的业务代码。
const validator = $(’#testView’).kendoValidator().data(‘kendoValidator’);
if(validator.validate()){ //如果通过
业务内容
}
required 必填标签
在html表单中加入这个标签是必填项目,在validationMessage标签中写入必填项没有通过验证后的,提示信息内容。
<input data-role="text" name="name"
required
validationMessage="名字不能为空"
data-bind="value:getUser.name" />
pattern 自定义正则判断
很多情况是需要自己定义一个新的验证规则来进行表单验证的,这个时候我们可以使用pattern
标签来定义正则,再通过data-pattern-msg标签来定义验证失败后的提示信息内容。
<input type="text"
pattern="\d{3}"
data-bind="value:getUser.money"
data-pattern-msg="请录入数字"
name="money" id="money" />
Number 数字max/min
验证数字类型的表单最大值与最小值。
<input type="number" name="age" min="18" max="42">
date日期类型验证
<input type="date" name="date" data-date-msg="请选择正确的日期类型">
高级应用自定义规则组件
除了上面的的内置消息,我们还可以定义自己的验证类型,创建不同的验证组件,为这些组件定义自己的消息提示。
- 创建一个 kendo.ui.ValidatorOptions 接口类型额验证
//创建验证组件
const zhtbs :kendo.ui.ValidatorOptions= {
validationSummary:false //必须定义的
}
- rules属性中,设置自定义规则方法。
//创建验证组件
const zhtbs :kendo.ui.ValidatorOptions= {
validationSummary:false, //必须定义的
rules: { //规则集合属性
custom: function(input:any) {//创建自己的验证规则方法
if (input.is('[name=namezht]')) {//判断表单的name是否是namezht
return input.val() === 'zht';//如果是正确,如果不是验证失败
}
return true;
}
}
}
-
表单中的每个元素都会运行rules中的自定义规则方法。
-
验证方法返回true为验证通过,方法false为验证失败。
-
在 messages属性中创建验证失败后的提示内容。rules中的验证方法名称
custom
与messages中的custom
名称是对应关系必须一样。
const zhtbs :kendo.ui.ValidatorOptions= {
validationSummary:false,
messages: { //提示信息属性
------- custom: '名字必须为zht' //创建custom验证失败后的提示信息
| },
| rules: {
| ------- custom: function(input:any) {
if (input.is('[name=namezht]')) {
return input.val() === 'zht';
}
return true;
}
}
}
data-[rule]-msg
[rule]
is the failing validation rule- 如果不想使用messages 属性的错误提示,可以在表单属性中定义提示信息
data-[rule]-msg
这里[rule]
自定义验证方法名称。
<input data-role="text" name="namezht" //验证表单名称 对应if (input.is('[name=namezht]'))
data-custom-msg="名称必须为zht" //错误信息提示
data-bind="value:getUser.namezht" />
- 自定义验证类装入验证器中
const zhtbs :kendo.ui.ValidatorOptions= {
validationSummary:false,
messages: {
custom: '名字必须为zht'
},
rules: {
custom: function(input:any) {
if (input.is('[name=namezht]')) {
return input.val() === 'zht';
}
return true;
}
}
//装入验证器中
const validator = $('#testView').kendoValidator(zhtbs).data('kendoValidator');
template.ts(模板)
----------------------------------------------------------------------------
<form id="testView">//验证form信息内容
<input name="name"
required
validationMessage="名字不能为空"
data-bind="value:getUser.name" />
<input
type="text"
pattern="\d{3}"
data-bind="value:getUser.money"
data-pattern-msg="请录入数字3位数字"
name="money" id="money" />
<input name="namezht" //验证表单名称 对应if (input.is('[name=namezht]'))
data-custom-msg="名称必须为zht" //错误信息提示
data-bind="value:getUser.namezht" />
<button type="button"data-bind="click:onSave" >提交信息验证</button>
</form>
- 自定义验证方法可以定义为表单的属性方便引用
const zhtbs :kendo.ui.ValidatorOptions= {
validationSummary:false,
rules: {
minsize:function(input:any){
if (input.is('[minsize]')){//判断表单是否有这个属性标签
if(input.val().length<10){//字符长度不能小于10
return false;
}
}
return true;
},
maxsize:function(input:any){
if (input.is('[minsize]')){//判断表单是否有这个属性标签
if(input.val().length>20){//字符长度不能大于20
//也可以在maxsize中设定最大值进行判断
//获得maxsize属性中设置的最大值进行
//alert(input[0].attributes.maxsize.value);
//if(input.val().length>input[0].attributes.maxsize.value)
return false;
}
}
return true;
}
}
}
template.hbs(模板)
----------------------------------------------------------------------------
// maxsize最大字符长度 minsize最小字符长度 required 不为空
<textarea name="bz" maxsize="20" minsize required
data-minsize-msg="字符不能小于10个" data-maxsize-msg="字符不能大于20个"
data-bind="value:getUser.bz" id="bz" />
开发人员可以根据不同的业务需求来灵活的定义自己的验证方法,在将这些方法与表单进行绑定与关联,来完成自己的业务需求。
data-for 验证提示
开发人员可以自己定义信息提示位置,通过元素data-for="名称"绑定对应验证表单验证元素的名称,在定义一个css样式的.k-invalid-msg
就完成了。注意使用了data-for 元素必须使用class="k-invalid-msg"来定义样式内容。
// class="k-invalid-msg"必须存在
<span class="k-invalid-msg" data-for="namezht"></span>
|
<input data-role="text" name="namezht" <--| //验证提示名称对应关系建立
data-bind="value:getUser.namezht" />
DropDownList
From表单(例子7)
kendo表单属性的组件在template.hbs模板中使的时候,需要定义在 data-role
元素中,名字是小写。
参考test7中的代码
checkbox 复选框
使用html中自带的属性checkbox元素进行复选框操作。
- 通过jquery map方法获得复选框内容
template.hbs(模板)
----------------------------------------------------------------------------
数据一
<input value="数据一" type="checkbox" name="checkname1" />
数据二
<input value="数据二" type="checkbox" name="checkname1" />
数据三
<input value="数据三" type="checkbox" name="checkname1" />
<button data-role="button"
type="button"
data-bind="click:onSave">提交信息验证</button>
ViewModel.ts(业务逻辑类)
-------------------------------------------------------------------
//获得复选框中内容
public onSave():void{
//通过jquery map方法获得复选框中的value
const cname1=$.map($('input[name=\'checkname1\']:checked')
.map(function(data,value){
// console.log(data,$(value).val());
return $(value).val();
}),n=>{return n});
this.getUser.set('checkname1',cname1);//复选框内容保存到页面数组
}
- 默认值通过kendo mvvm中的data-bind="checked:变量"方式进行设置
this.getUser.set('ischeck',true);//默认选择复选框
数据一
<input value="数据一"
type="checkbox" name="checkname1"
data-bind="checked:getUser.ischeck"/>
DropDownList 下拉列表
html中的select下拉表单功能,它比select功能更为强大。
//data-role="dropdownlist"下拉列表
<input data-role="dropdownlist" name="name"
data-source="['下拉一','下拉二']" //静态定义下拉内容
data-bind="value:getUser.name" />
- 定义有数据源的下拉列表
- data-text-field= 数据源中对象的引用名字 html 中select opetion text
- data-value-field=数据源中对象的引用名字 html 中select opetion value
- data-auto-bind=“false” 是否自动加载数据源
- data-bind=value:getUser.name1 获得是整个数据源中index索引位置的对象,不是一个值需要在后台将值取出,进行重新操作。
ViewModel.ts(业务逻辑类)
-----------------------------------------------------------------------------
this.dataSource=new kendo.data.DataSource({data:[
{name:'z1',id:12,'bz':'2222'},
{name:'z2',id:2,'bz':'2222'},
{name:'z3',id:5,'bz':'2222'},
]});//创建一个数据源
template.hbs(模板)
----------------------------------------------------------------------------
数据源下拉
<input data-role="dropdownlist" name="name1"
data-text-field="name"
data-value-field="id"
data-auto-bind="false"
data-bind="value:getUser.name1,source:dataSource" />//引入数据源
ViewModel.ts(业务逻辑类)
----------------------------------------------------------------------------- public onSave():void{
//获得带数据源的下拉列表的值
//获得的是整个 {name:'z1',id:12,'bz':'2222'}结构
alert(this.getUser.get('name1').name);
//重新操作封装下拉列表的数据值内容
this.getUser.set('name1',this.getUser.get('name1').name)
}
-
下拉组件绑定事件
可以绑定以下几种事件 change ,close,open, select
//数据源下拉加事件
<input data-role="dropdownlist" name="name2"
data-text-field="name"
data-value-field="id"
data-auto-bind="false"
data-bind="value:getUser.name2,source:dataSource,events:{select: onLSelect}" />
/**下拉事件**/
public onLSelect(e:any):void{
alert(e.item.text());
}
- 通过id来操作下拉组件
在逻辑类中通过下拉组件的id,获得下拉组件模板中的引用 。获得下拉组件的引用后,使用jquery的方法操作这个下来组件。
const dropdownlist = $('#name1').data('kendoDropDownList');
dropdownlist.select(1);
-
下拉框默认值设置
操作逻辑类中与元素绑定的数据模型对象,为下拉框赋默认值。一般是在构造函数中进行默认值设置。
data-bind=value:getUser.name1 在逻辑类中给name1 一个值
export default class ViewModel extends kendo.data.ObservableObject {
constructor() {//构造函数中创建下拉组件的引用
super();
this.getUser=new MainModel();//数据初始化
this.dataSource=new kendo.data.DataSource({data:[
{name:'z1',id:12,'bz':'2222'},
{name:'z2',id:2,'bz':'2222'},
{name:'z3',id:5,'bz':'2222'},
]});//创建一个数据源
this.getUser.set('name1',5);//设置下拉框默认值
}
}
DropDownTree 下拉树
下拉树组件与复选框组合使用的一个特色组件。
-
mvvm数据源使用HierarchicalDataSource
这个组件使用的数据源是特色的kendo.data.HierarchicalDataSource数据源,使用一般的数据源DataSource会报错。
-
data-bind=“value:getUser.nametree” 设置下拉列表值
ViewModel.ts(业务逻辑类)
-----------------------------------------------------------------------------
public dropdowntreeSource:kendo.data.DataSource;
constructor() {
this.dropdowntreeSource=new kendo.data.HierarchicalDataSource({data:[
{id: 1, text: '一号',items: [
{ id:11,text: '1.1号' },
{ id:11,text: '1.2号' }
]},
{id: 2, text: '二号',items: [
{ id:21,text: '2.1号',
items: [
{ id:211,text: '2.2.1号' }
]}
]}
]});//下拉多选框树
}
template.hbs(模板)
----------------------------------------------------------------------------
<input data-role="dropdowntree" name="droptreename"
data-placeholder="选择树内容"
data-text-field="text"
data-value-field="id"
data-checkboxes="true"
data-value-primitive="true"
style="width:70%;"
data-bind="source:dropdowntreeSource" />
- data-text-field= 数据源中对象的引用名字 html 中select opetion text。
- data-value-field=数据源中对象的引用名字 html 中select opetion value。
- data-checkboxes= 树为复选框树。
普通from表单绑定
from表单的普通元素也可以通过kendo数据模型进行值绑定,定义一个json数组[{id’’:,name:’’},{id’’:,name:’’}]将它装入数据模型中,在template.hbs(模板)中定义一个 select下拉框, 使用这个data-bind="source:getUser.sel"绑定这个数组,下拉框显示这个数组对应的数据内容。
单选框与复选框同样的原理,定义一个显示数组,与template.hbs(模板)中的单选框和复选框元素对应绑定data-bind="checked:数组"初始化选择项。
export default class ViewModel extends kendo.data.ObservableObject {
//构造函数
constructor() {
super();
this.getUser=new MainModel();//数据初始化
this.getUser.set('sel',[//普通下拉框
{ id: 1, name: '部门一' },
{ id: 2, name: '部门二' },
{ id: 3, name: '部门三'}
]);
this.getUser.set('isxn',[//普通多选框初始值
'选择一', '选择三'
]);
this.getUser.set('selectedColor','女');
}
public onSave():void{
alert('普通下拉'+this.getUser.get('puname').id);
//this.getUser.get('puname').name
//
alert('文本框'+this.getUser.get('inputValue')
+''+this.getUser.get('textareaValue'));
//
alert('选择框'+this.getUser.get('selectedColor')
+' '+this.getUser.get('isxn')[0]);
//
}
}
template.hbs(模板)
----------------------------------------------------------------------------
<input data-bind="value:getUser.inputValue" />
<textarea data-bind="value:getUser.textareaValue"></textarea>
普通下拉
<select
data-text-field="name" //普通下拉框name属性
data-value-field="id" //select value值
//source:绑定下拉集合对象,value下拉框值
data-bind="source:getUser.sel,value:getUser.puname">
</select>
<input type="radio"
name="sex" value="男"
data-bind="checked:getUser.selectedColor" />男
<input type="radio"
name="sex" value="女"
data-bind="checked:getUser.selectedColor" />女
选择一
<input value="选择一"
type="checkbox" name="checkname1"
data-bind="checked:getUser.isxn"/>
选择二
<input value="选择二" type="checkbox"
name="checkname1"
data-bind="checked:getUser.isxn"/>
选择三
<input value="选择三" type="checkbox"
name="checkname1"
data-bind="checked:getUser.isxn"/>
第五章 DataSource操作
KenDo所有组件与服务器进行连接通信,将ype服务器中的数据拿到数据源DataSource中,在通过DataSource类的将服务器的数据赋值给kendo其他组件。在kendo所有mvvm模式中与服务器连接的请求都是用DataSource类来实现的,DataSource类中提供啦大量的Ajax实现方法。也可以根据业务的实际情况重新定义新的方法覆盖给DataSource类中的方法,在事件中引用这些方法来实现业务功能。
DataSource 访问服务器 transport属性
数据源远程服务配置-URL,HTTP动词,HTTP标头等访问请求功能,都会使用到transport
选项。transport
提供了查询,保存,修改,删除4个通用方法,使用者通过设置这4个方法达到与远程服务器进行通信,进行对应的业务数据交互。
方法 | 功能 | 备注 |
---|---|---|
create | 新增 | |
read | 查询 | |
delete | 删除 | |
update | 修改 |
示例创建一个数据源,在数据源transport属性中创建一个查询方法。
ViewModel.ts(业务逻辑类)
--------------------------------------------------------------------
export default class ViewModel extends kendo.data.ObservableObject {
//定义远程连接数据源
public dataSource = new kendo.data.DataSource(
{//定义连接远程服务器,数据源信息内容。
transport: {
read: {//定义查询方法
url: '/zhtbs/zhtbs/test',//服务访问路径地址
dataType: 'json',//返回数据类型
type: 'POST'//数据方类型
}
}
}
);
//构造函数
constructor() {
super();
//调用数据源中的查询方法将查询到的数据传给kendoUI绑定数据
this.dataSource.read();
}
}
template.hbs(模板)
---------------------------------------------------------------
<div data-role="grid"
data-selectable="multiple,row"
data-columns="[
{ field: 'id', title: 'id', width:150 },
{ field: 'name', title: '名字', width:200 }
]"
data-editable="popup"
data-bind="source:dataSource"
style="height:300px; margin-top:10px;"
id="grid"></div>
transport属性 read方法(例子8)
read方法核心是使用了Jquery.ajax方法发起远程服务请求,将远程服务获得到数据绑定给KendoUI组件。read方法最重要的属性有url,type,dataType。分别是url服务器路径,type请求类型,dataType数据返回类型。在后边也会介绍read中的其他属性。read的属性也和create,delete,update等方法中的属性同时通用。
1 创建服务器数据
使用spring boot 架构创建一个RestController容器。
@RestController
public class RestMainController{
@PostMapping("/zhtbs/test")
public List getFind(){
List list=new ArrayList();
Map map=new HashMap();
map.put("id","1");
map.put("name","zht");
list.add(map);
return list;
}
}
2 创建一个DataSource 数据源
- 创建一个数据源类。
- 在数据源定义transport属性。
- transport属性中创建read()方法。
- 在read()方法中定义服务器远程访问路径,类型等等内容。
- 在构造函数调用this.dataSource.read();方法初始化DataSource中的数据参数。
ViewModel.ts(业务逻辑类)
-----------------------------------------------------------------------------
export default class ViewModel extends kendo.data.ObservableObject {
//定义远程连接数据源
public dataSource = new kendo.data.DataSource(
{//定义连接远程服务器,数据源信息内容。
transport: {
read: {//定义查询方法
url: '/zhtbs/zhtbs/test',//服务访问路径地址
dataType: 'json',//返回数据类型
type: 'POST'//数据方类型
}
}
}
);
//构造函数
constructor() {
super();
this.dataSource.read();//调用数据源中的查询方法将查询到的数据传给kendoUI绑定数据
}
}
3 在模板中将数据源与KendoUI组件进行绑定data-bind=“source:dataSource” 。
<div data-role="grid"
data-selectable="multiple,row"
data-columns="[
{ field: 'id', title: 'id', width:150 },
{ field: 'name', title: '名字', width:200 }
]"
data-editable="popup"
data-bind="source:dataSource"
style="height:300px; margin-top:10px;"
id="grid"></div>
这是一个完成的DataSource 数据源与web服务器通信的mvvm代码示例。web服务器负责产生业务数据代码,通过前台脚本的DataSource类进行ajax 数据通信,DataSource获得到web服务器产生的数据,将它绑定给模板中的kendo组件。
transport属性 create和update方法(例子8)
在KenDoMvvm框架中我们使用 DataSource 中的create和update方法向远处服务器发送数据进行新增和修改操作。开发者需要覆盖和重新定义这两个方法中的属性,然后执行dataSource.sync();方法DataSource 就会提交数据高远程服务中。
这里有一个问题dataSource.sync();怎么知道我们是新增数据还是修改数据呢?原来问题的答案在dataSource 类中的 schema: { model: { id: ‘id’} } schema下的model方法的定义一个添加与删除使用的数据模型,如果传送的数据中没有id属性对应的数据就是新增,如果有id属性的数据就是修改方法。
1 创建一个dataSource数据源类
- 定义create方法中的属性。
- 定义update方法中的属性。
- 定义参数过滤器 parameterMap方法,自己根据传入的参数数据进行对应的过滤操作。例如将kendo的数据模型的数据结构转换成json对象的数据结构。
- 定义数据模型,使用数据模型中的主键设置来判断是新增还是修改。schema.model.id(重点id值是kendo唯一判断新增与修改的方法)
ViewModel.ts(业务逻辑类)
---------------------------------------------------------------------------
export default class ViewModel extends kendo.data.ObservableObject {
private product = kendo.data.Model.define({//定义数据模型
id: 'id'//定义添加与删除对比组键 <---------------------------------------|
}); |
//定义远程连接数据源 |
public dataSource = new kendo.data.DataSource( |
{ |
transport: { |
read: { |
url: '/zhtbs/zhtbs/test', |
dataType: 'json', |
type: 'POST' |
}, |
create: { |
url: '/zhtbs/zhtbs/save', |
dataType: 'json',//参数类型 |
contentType: 'application/json;charset=UTF-8',//协议类型 |
type: 'POST' |
}, |
update: { |
url: '/zhtbs/zhtbs/up', |
dataType: 'json',//参数类型 |
contentType: 'application/json;charset=UTF-8',//协议类型 |
type: 'POST' |
}, |
parameterMap: function(data) {//参数过滤器 |
console.log(kendo.stringify(data)); |
//kendo.stringify将数据对象转成对应个数据结构 |
return kendo.stringify(data); |
} |
}, |
batch: false, |
schema: { |
model: this.product <--------------------------------
} //引入数据模型,id数据定义数据中主键属性名称 |
} |
); |
//构造函数 |
constructor() { |
super(); |
this.dataSource.read(); |
} |
public onfind():void{ |
const p=new this.product();//创建数据模型类 |
p.set('name','ddddd'); |
//没有定义id 执行create 如果定义id修改update |
//p.set('id','1222'); <-----------------------|
this.dataSource.add(p);//模型数据放入数据源类
this.dataSource.sync();//调用新增与修改
}
}
2 Spootboot 对应的容器内容
- 注意application/json;charset=UTF-8协议 springboot需要使用这个注解@RequestBody
@RestController
public class RestMainController{
@PostMapping("/zhtbs/save")
//@RequestBody 对应http协议application/json;charset=UTF-8 参数类型json格式
public List save(@RequestBody Map user){
System.out.println(user.get("name"));
return user;
}
@PostMapping("/zhtbs/up")
//@RequestBody 对应http协议application/json;charset=UTF-8 参数类型json格式
public List up(@RequestBody Map user){
System.out.println(user.get("name"));
System.out.println(user.get("myid"));
return user;
}
}
3 模板页面
<input type="button" value="添加与修改测试" data-bind="click:onfind" />
<div data-role="grid"
data-selectable="multiple,row"
data-columns="[
{ field: 'myid', title: 'id', width:150 },
{ field: 'name', title: '名字', width:200 }
]"
data-editable="popup"
data-bind="source:dataSource"
style="height:300px; margin-top:10px;"
id="grid"></div>
</div>
DataSource数据源的添加与修改方法主要的难点问题是定义数据 Model,这个模型获得数据与id主键内容与实际业务数据模型是一个类型才可以起到作用。
DataSource Model 数据模型定义(例子8)
在DataSource 数据源类中新增,修改,删除的时候,需要对DataSource 数据源中schema.model属性进行定义,创建一个数据模型与schema.model进行绑定。数据模型通常是kendo.data.Model是这个类型的类或者是继承了ObservableObject这个类型的自定义类,并可以扩展和自定义字段和方法。
每个数据源DataSource 对象都需要定义一个对应的数据模型,使用schema.model属性为数据源指定对应的数据模型类型引用。
这个数据模型可以和表单或者其他的业务数据模型使用同一个引用。
//定义远程连接数据源
public dataSource = new kendo.data.DataSource(
{
transport: {
},
schema: {
model: this.product//定义数据源的数据模型
}
}
);
1 使用define创建Model对象
- 使用define方法初始化一个Model对象。
private product = kendo.data.Model.define({//定义数据模型
});
2 id主键标志设置
- 在kendo数据模型 Model中id默认值也是id,
- 如果id属性改成其他值,在使用的时候需要进行特殊处理,将改的id值与Model中默认的id值进行互换。
private product = kendo.data.Model.define({
id: 'id'//定义主键标志
});
3 创建一个数据模型的引用
- 在引用中可以使用set 和get 方法来设置数据模型中的属性值。
- Model 的id主键标识必须定义。
private product = kendo.data.Model.define({
id: 'id'//定义主键标志
});
const p=new this.product();//创建一个数据类型
p.set('name','ddddd');
p.set('id','1222');
console.log(p.get('id'));
console.log(p);
4 fields创建数据模型其他关系属性
- 模型的列配置。包括模型的列的字段名称,字段属性,默认值,校验方法等。
private product = kendo.data.Model.define({
id: 'id'//定义主键标志
fields: {
id: { type: 'string', editable: false, nullable: true},//ID
name: { type: 'string', validation: { required: false } },//名称
},
});
值名称:{ 值属性内容 }
属性 | 作用 |
---|---|
type | 定义数据number,string,date |
editable | 此字段将不可编辑(默认值为true) |
nullable | 将不分配默认值(默认值为false) |
validation | 表单验证{ required: false }required 不能为空 |
5 自定义id主键标志
private product = kendo.data.Model.define({
id: 'myid' //如果自己定义一个主键名称
});
在这个版本低kendo使用 this.dataSource.sync()方法进行新增与修改的时候需要特殊处理一下。如果执行修改方法,需要给数据模型id属性赋值,让id不能为空,这样在kendo执行DataSource 才会执行修改方法。
- 数据模型id是判读新增与修改的标识,如果this.puser.set(‘id’,null);id设置为空就是新增,如果有值this.puser.set(‘id’,122)就是修改。
public onsave():void{
this.puser.set('name','ddddd');
this.puser.set('myid','11');
this.dataSource.add(this.puser);
this.dataSource.sync();
}
public onup():void{
this.puser.set('name','ddddd');
this.puser.set('myid','11');
this.puser.set('id','11'); //如果不设置id属性是新增,如果设置id属性是修改
this.dataSource.add(this.puser);
this.dataSource.sync();
}
transport属性 destroy删除方法(例子9)
在DataSource中的destroy方法负责执行删除方法,destroy执行与远程服务器进行通行。运行成功后数据源DataSource类同时会执行删除方法,将数据源中对应的数据模型也同时删除掉。
DataSource数据源是通过remove方法从数据源中删除的对应数据模型。remove方法中装入的是要删除的数据模型。数据模型中主要的是数据模型主键,一定要给主键属性设置值。
1 定义DataSource中的删除方法
- 定义要删除执行方法this. dataSource.remove(this.puser);
export default class ViewModel extends kendo.data.ObservableObject {
private product = kendo.data.Model.define({
id: 'myid'
});
//定义远程连接数据源
public dataSource = new kendo.data.DataSource(
{
transport: {
destroy:{
url: '/zhtbs/zhtbs/del',
dataType: 'json',
contentType: 'application/json;charset=UTF-8',
type: 'POST'
} ,
parameterMap: function(data) {
console.log(kendo.stringify(data));
return kendo.stringify(data);
},
},
batch: false,
schema: {
model: this.product
}
}
);
public ondel():void{
this.puser.set('myid','2');//删除模型主键id
this.puser.set('id','2');//删除模型主键id
this. dataSource.remove(this.puser);//删除数据源中对应的数据模型数据
this.dataSource.sync();//执行远程服务器删除
}
}
2 Spring boot方法
- 注意application/json;charset=UTF-8协议 springboot需要使用这个注解@RequestBody
@PostMapping("/zhtbs/del")
public Map del(@RequestBody Map user){
System.out.println("delete "+user.get("name")+" "+user.get("myid"));
return user;
}
DataSource查询条件设置(例子10)
DataSource.read(数据模型)方法将查询条件传给远程服务器,远程服务器通过查询条件查询出相应的数据在返还给DataSource数据源。
- 使用read(数据模型) 方法传查询条件信息。
1 在mvvm逻辑类中定义一个全局属性的查询条件数据模型
private product = kendo.data.Model.define({
id: 'myid'
});//初始化一个数据模型
protected puser=new this.product();//创建这个数据模型的应用对象
2 在mvvm逻辑类封装一个全局引用,方便在html模板中data-bind=进行数据绑定
//表单数据和行数据 Model类
get getUser(): kendo.data.Model{
return this.puser;
}
3 在html模板中data-bind=数据绑定建立对应关系
- data-bind=“value:puser.name” 使用kendo的data-bind绑定value值。
<input data-role="text" type="text" class="k-textbox" name="name"
data-bind="value:puser.name"
style="width:100px;border:0;" />
<input data-role="text" type="text" class="k-textbox" name="age"
data-bind="value:puser.age"
style="width:100px;border:0;" />
<input type="button" value="查询" data-bind="click:onFind" />
4 在mvvm逻辑类封定义查询方法
- 将html模板中获得查询条件数据的数据模型传给dataSource数据源的read方法。
public onFind():void{
this.dataSource.read(this.getUser);
}
5 在spring boot容器中获得到查询条件查询数据库
- 注意application/json;charset=UTF-8协议 springboot需要使用这个注解@RequestBody
@PostMapping("/zhtbs/pagelist")
//
public List pagelist(@RequestBody Map user){
System.out.println("page "+user);
List list=new ArrayList();
Map map=new HashMap();
map.put("myid","1");
map.put("name","zht");
list.add(map);
return list;
}
6 mvvm完成查询示例
export default class ViewModel extends kendo.data.ObservableObject {
private product = kendo.data.Model.define({
id: 'myid'
});//创建查询数据模型
protected puser=new this.product();//定义查询模型数据引用
//定义远程连接数据源
public dataSource = new kendo.data.DataSource(
{
transport: {
read: {
url: '/zhtbs/zhtbs/pagelist',
dataType: 'json',
type: 'POST',
contentType: 'application/json;charset=UTF-8',
},
parameterMap: function(data) {
console.log(kendo.stringify(data));
return kendo.stringify(data);
},
},
batch: false,
schema: {
model: this.product
}
}
);
//构造函数
constructor() {
super();
this.dataSource.read();
}
public onFind():void{//定义查询方法
this.dataSource.read(this.getUser);//将查询数据传给查询方法,发送给远程服务器。
}
//定义查询条件html模本中的引用对象
get getUser(): kendo.data.Model{
return this.puser;
}
}
template.hbs(模板)
----------------------------------------------------------------------------
<input data-role="text" type="text" class="k-textbox" name="name"
data-bind="value:puser.name" style="width:100px;border:0;" />
<input data-role="text" type="text" class="k-textbox" name="age"
data-bind="value:puser.age" style="width:100px;border:0;" />
<input type="button" value="查询" data-bind="click:onFind" />
<div data-role="grid"
data-selectable="multiple,row"
data-columns="[
{ field: 'myid', title: 'id', width:150 },
{ field: 'name', title: '名字', width:200 }
]"
data-editable="popup"
data-bind="source:dataSource"
style="height:300px; margin-top:10px;"
id="grid"></div>
DataSource分页属性 (例子10)
在DataSource查询分页时候需要设定几个属性和grid组件中的一些属性设置才可以达到分页的效果。
1 schema.data 数据内容属性名称。
2 schema.total 数据总条。
3 pageSize 每分显示几条数据。(设置默认是10条)
后台服务器传过来的数据是json格式,需要与DataSource中的分页属性建立对应关系 。
例如: 服务器端生产数据为{data:[ 数据内容],count:‘总条数’}
// {data:[ 数据内容],count:'总条数'}
schema: {
data: 'data',
total: 'count',
model: this.product
},
pageSize:2 //设置为每页2条数据
在html中grid组件设置为分页属性 data-pageable
- data-pageable 属性中的pageSize初始分页
- data-pageable 属性中 pageSizes: [2, 5, 10] 为可改变的每页数据条数
<div data-role="grid"
data-selectable="multiple,row"
data-pageable="{
pageSizes: [2, 5, 10],
pageSize: 2,
}"
data-columns="[
{ field: 'myid', title: 'id', width:150 },
{ field: 'name', title: '名字', width:200 }
]"
data-editable="popup"
data-bind="source:dataSource"
style="height:300px; margin-top:10px;"
id="grid"></div>
Spring boot 容器中的设置
- 方位数据类型为json格式,json包含两个属性一个是data内容,count总条数。
@PostMapping("/zhtbs/pagelist")
public Map pagelist(@RequestBody Map user){
System.out.println("page "+user);
List list=new ArrayList();
Map map=new HashMap();
map.put("myid","1");
map.put("name","zht");
list.add(map);
Map map1=new HashMap();
map1.put("myid","2");
map1.put("name","222vvv");
list.add(map1);
Map map2=new HashMap();
map2.put("myid","3");
map2.put("name","表33");
list.add(map2);
Map map3=new HashMap();
map3.put("myid","4");
map3.put("name","vcvccc");
list.add(map3);
Map map4=new HashMap();
map4.put("myid","5");
map4.put("name","555vvvv");
list.add(map4);
Map pagemape=new HashMap();
pagemape.put("data",list);//内容
pagemape.put("count",5);//总条数
return pagemape;
}
第六章 DataSource的mvvm综合使用
在实际项目开发中,每组页面都要完成查询,添加,修改,删除等基础操作,这些操作需要使用DataSource与远程服务器进行数据通行,将这些数据传递给数据库。我们通过下面的示例代码来描述在Kendo的mvvm中,是怎样巧妙的实现这些功能。
逻辑类ViewModel.ts(增删改查 例子11)
使用mvvm模式来进行一个页面中的增删改查的业务操作,首先我们要定义一个业务数据数据模型,这个数据模型要包含from表单中属性和table列表中的数据内容。
1 数据模型使用kendo模型基础类Model进行创建
使用kendo.data.Model.define初始化一个数据模型。使用id和fields 初始化数据模型内容。
export default class ViewModel extends kendo.data.ObservableObject {
//定义from与table中的数据模型内容
private product = kendo.data.Model.define({
id: 'myid',
fields: {//数据属性
name: {
from: 'name',
defaultValue: 'No title',
validation: { required:true } }
}
});
}
2创建数据模型的引用
使用new this.product(); 创建数据模型使用的引用。我们创建两数据模型的应用,一个放查询条件,一个用于from表单中增加和修改时候使用的数据。
protected puser=new this.product();//查询条件信息初始化
protected saveUpuser=new this.product();//用于新增与修改的数据模型
export default class ViewModel extends kendo.data.ObservableObject {
private product = kendo.data.Model.define({
id: 'myid',
fields: {//数据属性
name: { from: 'name', defaultValue: 'No title', validation: { required:true } }
}
});
protected puser=new this.product();//查询条件信息初始化
protected saveUpuser=new this.product();//用于新增与修改的数据模型
}
3 创建一个kendo grid组件的对应数据模型
用于获得grid组件中的数据内容,当用户点击grid组件中数据列表的内容时候,将点击行的数据转入到数据模型中来。
protected _tabledata: kendo.data.Model[] = [];//获得grid组件中的 数据模型数据 去的dataSource.data数据
export default class ViewModel extends kendo.data.ObservableObject {
private product = kendo.data.Model.define({
id: 'myid',
fields: {//数据属性
name: { from: 'name', defaultValue: 'No title', validation: { required:true } }
}
});
protected puser=new this.product();//查询条件信息初始化
protected saveUpuser=new this.product();//用于新增与修改的数据模型
//获得grid组件中的点击事件后选择的数据,这些数据模型是Model类型的数据
protected _tabledata: kendo.data.Model[] = [];
}
创建逻辑类中数据模型的引用别名,别名是为了在逻辑类中方便给数据进行赋值和数据传递的时候使用。和java中的get,set创建方式基本是一样的。
//表单数据和行数据 Model类
get getUser(): kendo.data.Model{
return this.puser;
}
//封装新增与删除的数据模型。定义他们的全局变量
get saveOrUpPojo(): kendo.data.Model{
return this.get('saveUpuser');
}
set saveOrUpPojo(userpojo:kendo.data.Model){
this.set('saveUpuser',userpojo);
}
//编辑grid组件行数据信息get set方法封装。面向对象编程
get userTabelData(): kendo.data.Model[] {
return this.get('_tabledata');
}
set userTabelData(selected: kendo.data.Model[]) {
this.set('_tabledata', selected);
}
4 创建一个数据源操作对象。
这个数据源操作对象封装了所有这个grid组件使用到的查询,增加,修改,删除与服务交互的业务逻辑。
//定义远程连接数据源
public dataSource = new kendo.data.DataSource(
{
transport: {
read: {//查询方法
url: '/zhtbs/zhtbs/pagelist',
dataType: 'json',
type: 'POST',
contentType: 'application/json;charset=UTF-8',
},
create: {//增加
url: '/zhtbs/zhtbs/save',
dataType: 'json',
contentType: 'application/json;charset=UTF-8',
type: 'POST'
},
update: {//修改
url: '/zhtbs/zhtbs/up',
dataType: 'json',
contentType: 'application/json;charset=UTF-8',
type: 'POST'
},
destroy:{//删除
url: '/zhtbs/zhtbs/del',
dataType: 'json',
contentType: 'application/json;charset=UTF-8',
type: 'POST'
} ,
parameterMap: function(data) {//数据模型过滤器服务与上面查询,增加,修改,删除
console.log(kendo.stringify(data));
return kendo.stringify(data);
},
},
batch: false,
schema: {//数据源对应的数据结构设置
data: 'data',//查询方法返回的数据结构中装数据的数据名称
//例如{count:5,data[{id:1,name:'zhtbs'},{id:2,name:'zht'}]}
total: 'count',//分页
model: this.product//对应的数据模型引用
},
pageSize:2
}
);
5 设置查询方法
每当用户在页面上点击查询按钮的时候,逻辑类中设置this.dataSource.read(this.getUser);将查询条件装入到数据源中的查询方法中。发送查询条件到服务器后台返回符合查询条件的数据结构给数据源,数据源在将数据传给kendo grid组件。
public onFind():void{
this.dataSource.read(this.getUser);
}
//构造函数
constructor() {
super();
this.dataSource.read();
}
6 设置新增与修改数据模型初始化内容
当用户在页面中点击增加按钮时候,程序调用逻辑类中的onSave增加初始化方法,方法中将from表中使用到的数据模型this.saveOrUpPojo赋值一个新的数据模型。模板中操作新增的时候,将值传递给新的数据模型。
用户在页面的grid组件中选择要修改的数据,grid组件点击事件将选中的数据模型传递到userTabelData中,点击修改按钮时候调用逻辑类中的onUpate()方法,程序从userTabelData数据模型中取出选中的数据模型赋值给this.saveOrUpPojo,this.saveOrUpPojo在 将要修改的数据传递给页面中的from数据中。
public onSave():void{//增加表单信息内容弹出页面初始化方法
this.saveOrUpPojo=new this.product();//
$('#saveup-edit').data('kendoWindow').title('新增').open().center();//弹出框弹出
}
public onUpate():void{//修改表单弹出页面,将grid中选中的数据信息装入到修改数据模型中
//grid组件中点击事件保存的修改数据模型传递给from表单数据模型
this.saveOrUpPojo=this.userTabelData[0];
console.log(this.saveOrUpPojo);
$('#saveup-edit').data('kendoWindow').title('修改').open().center();//弹出框弹出
}
7 设置新增与修改提交服务器方法
用户点击保存按钮时,程序调用onsumit方法。在onsumit方法中进行from验证,通过验证的数据判断一下是新增数据还是修改数据。如果是新增需要将这个数据模型 this.dataSource.add(this.saveOrUpPojo);加入到数据源中,在进行提交。
数据源中的新增与修改都是调用this.dataSource.sync()方法。
public onsumit():void{
//kendo表单验证
const validator = $('#testView').kendoValidator().data('kendoValidator');
if (validator.validate()) {//通过验证
console.log(this.saveOrUpPojo);
if(this.saveOrUpPojo.isNew()){//判断数据模型是否是新的,如果是新的调用数据源中的create方法
this.dataSource.add(this.saveOrUpPojo);
}//如果不是新的数据模型数据源调用update方法
this.dataSource.sync();
this.dataSource.read();
$('#saveup-edit').data('kendoWindow').close();
}
}
8 删除设置
用户在页面的grid组件中选择要删除的数据,与修改一样将通过grid组件点击事件将选中的数据模型传递到userTabelData中,在通过逻辑类中的赋值转换 this.saveOrUpPojo=this.userTabelData[0];将要删除的数据传给this.saveOrUpPojo数据模型, 再数据源中删除这个数据模型this. dataSource.remove(this.saveOrUpPojo);调用一下this.dataSource.sync();方法。
public onDel():void{
const promise = kendo.confirm('确认要删除么');
promise.done(()=>{ //获得弹出按钮确定方法
this. dataSource.remove(this.userTabelData[0]);
this.dataSource.sync();
});
}
模板template.hbs(增删改查 例子11)
模板html元素与逻辑类中的数据模型进行绑定,达到数据联动效果。当逻辑类中的数据模型中的数据发生变化,对应的模板中的html元素也有对应的数据变化。
- 页面布局分为 1查询按钮部分,2弹出框from表单,3 table列表kendo grid 组件三大部分。
-- 查询框 查询 添加 修改 删除
-- 弹出框window 表单from
-- kendo grid 组件
1 查询功能与按钮
查询条件数据模型与逻辑类中的查询数据模型进行数据绑定data-bind=“value:puser.name”。
将按钮事件与逻辑类中的方法进行绑定data-bind=“click:onFind”。
template.hbs(模板)
--------------------------------------------------------------------
<table>
<tr>
<td>
<input data-role="text"
type="text"
class="k-textbox"
name="name"
data-bind="value:puser.name"
style="width:100px;border:0;" />
</td>
<td>
<input type="button" value="查询" data-bind="click:onFind" />
<input type="button" value="添加" data-bind="click:onSave" />
<input type="button" value="修改" data-bind="click:onUpate" />
<input type="button" value="删除" data-bind="click:onDel" />
</td>
</tr>
</table>
ViewModel.ts(业务逻辑)
--------------------------------------------------------------------
protected puser=new this.product();//查询条件信息初始化
public onFind():void{查询业务}
public onSave():void{新增初始化}
public onUpate():void{修改初始化}
public onDel():void{删除信息}
2 弹出框from表单
新增与修改业务中我们使用到了kendo弹出框UI,使用者也可以根据实际的业务情况决定自己使用什么样式进行新增与修改业务操作。
在逻辑类中将表单的数据模型装入到 protected saveUpuser=new this.product(); saveUpuser对象引用中。模板将from中的元素与后台的数据模型进行绑定。
用户完录入数据,录入完成提交数据到逻辑类中的onsumit方法,onsumit方法通过数据源的对应方法将数据传递给服务端程序进行业务处理。
注意在from表单中一定要定义数据模型的id属性和数据模型中的主键对应的属性,后台逻辑类调用数据源方法进行新增与修改的时候需要判断这两个属性内容,如果属性有数据就是修改,没有数据为新增。
template.hbs(模板)
----------------------------------------------------------------------------
<div class="k-popup-edit-form"
data-role="window"//kendo UI 弹出框
data-visible="false"//弹出框隐藏状态
data-modal='true'
id="saveup-edit"//逻辑类引用 ${'#saveup-edit'}jquery引用
style="width:600px;">
<form id="testView"> //form表单验证引用 ${'#testView'}
<div>
<div class="k-edit-label">
<label for="name">名称</label>
</div>
<div>
<input data-role="text"
type="text"
class="k-textbox"
required //表单验证
name="name"
//数据模型绑定
data-bind="value: saveOrUpPojo.name"
style="width:40%;border:2;" />
</div>
</div>
<div class="k-edit-form-container" style="width: 100%;">
<input type="button"
value="提交代码"
data-bind="click:onsumit" />
<nput data-role="text"
//数据模型属性名称很重要一定要定义用来判断是新增与修改
type="hidden" name="myid"
data-bind="value: saveOrUpPojo.myid">//数据模型绑定
<nput data-role="text"
//数据模型属性名称很重要一定要定义用来判断是新增与修改
type="hidden" name="id"
data-bind="value: saveOrUpPojo.id">//数据模型绑定
</div>
</form>
</div>
ViewModel.ts(业务逻辑) -------------------------------------------------------------------
this.saveOrUpPojo=n、is.product(); //模板中绑定的数据模型引用
//新增与修改方法
public onsumit():void{
const validator = $('#testView').kendoValidator().data('kendoValidator');
if (validator.validate()) {
console.log('提交信息');
console.log(this.saveOrUpPojo);
if(this.saveOrUpPojo.isNew()){
this.dataSource.add(this.saveOrUpPojo);
}
this.dataSource.sync();
this.dataSource.read();
$('#saveup-edit').data('kendoWindow').close();
}
}
3 grid 列表组件
在模板中查询出来的数据使用kendo grid UI来显示出来,当用户需要修改数据的时候点击组件中的数据,我们使用 data-bind=“selected:_tabledata” 事件方法将选中的数据绑定给逻辑类中的数据模型,我们在逻辑类中奖选中的数据模型中的数据赋值给from表单中的数据模型来达到数据传递。
template.hbs(模板)
----------------------------------------------------------------------------
<div data-role="grid"
data-selectable="multiple,row"
data-pageable="{
pageSizes: [2, 5, 10],
pageSize: 2,
}"
data-columns="[
{ field: 'myid', title: 'id', width:150 },
{ field: 'name', title: '名字', width:200 }
]"
data-editable="popup"
data-bind="source:dataSource,selected:_tabledata"
style="height:300px; margin-top:10px;"
id="grid"></div>
ViewModel.ts(业务逻辑)
-------------------------------------------------------------------
protected _tabledata: kendo.data.Model[] = [];//获得grid组件中的
//编辑grid组件行数据信息get set方法封装。面向对象编程
get userTabelData(): kendo.data.Model[] {
return this.get('_tabledata');
}
set userTabelData(selected: kendo.data.Model[]) {
this.set('_tabledata', selected);
}
修改按钮隐藏(元素隐藏 例子12)
为了样程序看起来更加完美,当用户选择数据的时候按钮为可用状态,如果用户没有选择grid组件中的数据按修改钮为不可用状态。
在逻辑类中定义一个判断属性 this.set(‘isupflag’,false); ,在grid组件中定义一个点击事件方法当用户点击grid列表中的数据时候触发判断属性。在添加和修改按钮中绑定一个判断事件data-bind=“enabled:isButtonSav” ,在逻辑类中为这个判断事件赋值属性(true或者false)。
<input data-role="button"
type="button" value="添加"
data-bind="click:onSave,enabled:isButtonSav" />//定义按钮属性事件
<input data-role="button" type="button"
value="修改"
data-bind="click:onUpate,enabled:isButtonUp" />//定义按钮属性事件
<div data-role="grid"
data-selectable="multiple,row"
data-pageable="{
pageSizes: [2, 5, 10],
pageSize: 2,
}"
data-columns="[
{ field: 'myid', title: 'id', width:150 },
{ field: 'name', title: '名字', width:200 }
]"
data-editable="popup"
data-bind="source:dataSource,
selected:_tabledata,
events:{change:grid_change}" //定义点击事件
style="height:300px; margin-top:10px;"
id="grid"></div>
ViewModel.ts(业务逻辑)
---------------------------------------------------------------
public onsumit():void{
this.set('isupflag',false);//设置修改按钮不显示
}
public grid_change():void{
this.set('isupflag',true);//设置修改按钮显示
}
//添加按钮属性
public isButtonUp():boolean{
const isflag=this.get('isupflag');
if(isflag==''){
return false;
}
if(isflag==undefined){
return false;
}
return isflag;
}
//修改按钮属性
public isButtonSave():boolean{
const isflag=this.get('isupflag');
if(isflag==''){
return true;
}
if(isflag==undefined){
return true;
}
return !isflag;
}
第七章 路由与View转发页面
kendo mvvm框架转发页面与刷新页面的原理都是将 kendo组将加载在html元素中,需要使用视图模型绑定页面元素,将绑定的过程可以封装在kendo 的router类中就是路由,摸版中的元素触发事件,在事件通过路径调用路由的转发页面方法转发页面。
路由Router类转发(例子13)
路由Router类负责跟踪和维护视图的状态,并负责框架主页面和视图组件之间的相互引用功能,业务视图与框架元素html页面生成的对应关系都在路由类来进行控制。
在业务逻辑类中定义一个kendo的路由对象 public router = new kendo.Router();
使用路由对象的route方法将视图集合中的视图组件拿出,与新的视图展示元素进行绑定用于转发和引用新的页面而是用。
启动新的路由引用组件,完成新的页面转发请求。
本页引用其他页面到本页中来的例子
ViewModel.ts(业务逻辑)
---------------------------------------------------------------
//获得视图集合
import { routes } from '../../routes';
export default class ViewModel extends kendo.data.ObservableObject {
//构造函数
constructor() {
super();
}
//创建路由引用
public router = new kendo.Router();
public onFindpage():void{
//建立onFindpage 访问路径的与视图主键对应关系
this.router.route('onFindpage', function(args: any[]) {
$('#zhtmain').html('');//清空元素html内容
//在视图集合中获得这个视图组件信息。
//将视图组件中的视图元素与本页的显示元素建立联系
routes[1].callback(args).view.render($('#zhtmain'));--------|
}); |
//启动新路由对象 |
this.router.start(); |
//重定向转发页面 |
this.router.replace('onFindpage'); |
} |
} |
template.hbs(模板) |
--------------------------------------------------------------- |
<div class="mypage"> |
<table> |
<tr> |
<td> |
<input type="button" |
value="本页面元素引入其他页面" |
data-bind="click:onFindpage" /> |
</td> |
</tr> |
</table> |
<divid="zhtmain"> <-----------------------------------------------|
</div>
</div>
路由跳转到主页面
ViewModel.ts(业务逻辑)
---------------------------------------------------------------
//获得视图集合
import { routes } from '../../routes';
export default class ViewModel extends kendo.data.ObservableObject {
//构造函数
constructor() {
super();
}
//创建路由引用
public router = new kendo.Router();
public onMainpage():void{
//建立/onMainpage 访问路径的与视图主键对应关系
this.router.route('/onMainpage', function(args: any[]) {
$('#main-tabstrip').html('');//home.html主页面元素
//在视图集合中获得这个视图组件信息。
//框架页面home.html主页面元素
routes[3].callback(args).view.render($('#main-tabstrip'));--|
}); |
//启动新路由对象 |
this.router.start(); |
//重定向转发页面 |
this.router.replace('/zhtbs/test2'); |
} |
} |
home.html(模板) |
--------------------------------------------------------------- |
<div id="main-tabstrip" class="main_container" |
style="width: 99.5%;"> <--------------------------------|
Tab页面跳转
ViewModel.ts(业务逻辑)
---------------------------------------------------------------
//引用主框架的路由引用
import { navigate } from '../../globals';
export default class ViewModel extends kendo.data.ObservableObject {
//构造函数
constructor() {
super();
}
public onTab():void{
navigate('/zhtbs/test8');
}
}
View类转发跳转页面(例子13)
View 类是kendo中专门负责页面模板元素与业务逻辑元素进行绑定关系的类型,可以用于页面元素显示html功能的类。
html页面元素调用其他视图方法是在逻辑类中引入视图类 import 引用名称 from ‘…/test2/index’; 在使用这个kendo 视图组件的render方法与html页面元素进行绑定。
本页html元素调用其他逻辑视图
ViewModel.ts(业务逻辑)
---------------------------------------------------------------
import testindex from '../test2/index';//引入逻辑视图
export default class ViewModel extends kendo.data.ObservableObject {
public showviewtest2():void{
$('#zhtvim').html('');//清空视图组件
//将这个视图组件与页面中的html元素绑定
testindex().view.render($('#zhtvim'));
}
}
template.hbs(模板)
---------------------------------------------------------------
<input type="button"
value="view本页引用列二"
data-bind="click:showviewtest2" />
<div id="zhtvim">//页面引入视图元素
</div>
new kendo.View(模板引用,kendo对象模型)
我们也可以使用创建一个新的kendo view组件的在业务模板中(template.hbs)引入这个新的视图元素内容。创建新的视图组件过程
1 先创建一个新的模板页面(名称.hbs)
2 在业务逻辑类中导入这个模板
3 创建新的视图组件,将模板导入给这个视图组件
4 创建一个新的事件和数据模型赋值给视图组件类
5 将视图组件与模板中的元素绑定
| import page1 from './page1.hbs';//创建一个新模板
export default class ViewModel extends kendo.data.ObservableObject {
public showviewtest3():void{
$('#zhtvim').html('');
const foo={zht:function(){//定义事件与数据对象------------------
alert('调用我神不神奇'); |
}}; |
const view = new kendo.View(//创建一个新的视图组件 |
page1({name:'zhtbs'}),//引入模板对象与模板用到的数据 |
{model: foo});//引入kendo对象模型 |
view.render($('#zhtvim'));//绑定模板的元素 |
} |
} |
page1.hbs(引入模板) |
--------------------------------------------------------------- |
<div class="mypage"> |
我是新来的页面{{name}} |
<input type="button" value="调用事件" data-bind="click:zht" /> <--|
</div>
new kendo.View(模板引用,kendo对象模型)逻辑类中引入其他业务主件
我们在ViewModel.ts 类中创建一个新的业务逻辑类,我们在将这个新的业务逻辑类与新的模板进行绑定,在将绑定的对象与页面中的html元素进行关联。
import page2 from './page2.hbs';
export default class ViewModel extends kendo.data.ObservableObject {
public showviewtest4():void{
$('#zhtvim').html('');
const view = new kendo.View(
page2({name:'zhtbs'}),
{model: new zhtbs()});//绑定逻辑类------------|
view.render($('#zhtvim')); |
} |逻辑类与视图绑定
} |
class zhtbs{ <----------------------------------|
public dataSource: kendo.data.DataSource;//创建数据源引用
//构造函数
constructor() {
this.dataSource=new
kendo.data.DataSource({data:[//数据源部分
{name:'z1',age:12,'bz':'备注1',
ct:'鞍山',pho:'122332323232',
date: new Date(),
number: 23.4433},
{name:'z2',age:1333,'bz':'看看我',
ct:'鞍山',pho:'122332323232', date: new Date(),
number: 123.443223},
{name:'z3',age:1333,'bz':'我来了啦啦',
ct:'沈阳',pho:'122332323232',
date: new Date(), number: 3.00}
]});//创建一个数据源
}
}
page1.hbs(引入模板)
---------------------------------------------------------------
<div data-role="grid" // UI 组件类型,grid组件
data-columns="[
{ field: 'name',//this.dataSource中name属性对应的值
title: '名字',//列名称
width:150
},
{ field: 'bz', //this.dataSource中bz属性对应的值
title: '备注',
width:200
},
{ command: ['edit', 'destroy'] }
]"
data-bind="source:dataSource"
data-editable='inline',
style="height:150px; margin-top:10px;"
id="grid2"></div>
</div>
Router路由与View组合使用(例子14)
在实际的开发中通常Router路由与View要组合在一起进行使用,要使用路由的router方法将访问路径,视图,路由,页面元素绑定在一起。
this.router.route('/page1', function() {//url路径
$('#zhtmain').html('');
new kendo.View(page1({name:'访问视图模板1'}), //视图
{model:foo}).render($('#zhtmain'));//业务逻辑类与页面元素
});
下面是创建一个自定义视图,外部引入视图加入路由,在页面中调用的例子。
import page1 from './page1.hbs';//引入模板
import page2 from './page2.hbs';//引入模板
import test6 from '../test6/index';//引入视图
import test5 from '../test5/index';//引入视图
export default class ViewModel extends kendo.data.ObservableObject {
public router = new kendo.Router();//创建路由
//构造函数
constructor() {
super();
this.init();
}
//初始化
public init():void{
const foo={zht:function(){
alert('调用我神不神奇');
}};
//路由路径url与视图,页面元素绑定在一起
this.router.route('/page1', function() {
$('#zhtmain').html('');
new kendo.View(page1({name:'访问视图模板1'}),
{model: foo}).render($('#zhtmain'));
});
this.router.route('/page2', function() {
$('#zhtmain').html('');
new kendo.View(page2({name:'访问视图模板2'}),
{model: new zhtbs()}).render($('#zhtmain'));
});
this.router.route('/page3', function() {
$('#zhtmain').html('');
test6().view.render($('#zhtmain'));
});
this.router.route('/page4', function() {
$('#zhtmain').html('');
test5().view.render($('#zhtmain'));
});
this.router.start();
}
//路由页面转发事件
public onPage(e:any):void{
//this.router.navigate
this.router.navigate(e.target.dataset.url);
}
}
class zhtbs{
public dataSource: kendo.data.DataSource;//创建数据源引用
//构造函数
constructor() {
this.dataSource=new kendo.data.DataSource({data:[
{name:'z1',age:12,'bz':'备注1',ct:'鞍山',
pho:'122332323232', date: new Date(),
number: 23.4433},
{name:'z2',age:1333,'bz':'看看我',ct:'鞍山',
pho:'122332323232', date: new Date(),
number: 123.443223},
{name:'z3',age:1333,'bz':'我来了啦啦',ct:'沈阳',
pho:'122332323232', date: new Date(),
number: 3.00}
]});//创建一个数据源
}
}
template.hbs(模板)
------------------------------------------------------
<div class="mypage">
//菜单区域
<div id="zhtleft" style="float:left;width:40%;
background-color:bisque;height:400px;">
<div data-bind="click:onPage" data-url="/page1">页面一</div>
<div data-bind="click:onPage" data-url="/page2">页面二</div>
<div data-bind="click:onPage" data-url="/page3">页面三</div>
<div data-bind="click:onPage" data-url="/page4">页面四</div>
</div>
<div id="zhtmain" style="float:left;width:60%;height:400px;">
页面显示区域
</div>
<div style="clear: both;"></div>
</div>
第八章 kendo组件与树组件
kendo组件中的模板绑定是最常使用到的开发技巧之一,模板语法是kendo mvvm模式中必须掌握的知识点。在开发中会大量的使用到kendo绑定页面元素遍历数据模型数据,判断语法来进行业务逻辑判断。
kendo 组件元素 (例子15)
kendo类也是kendo中的基本组件,包含了很多通用的功能。
kendo 元素绑定bind(例子15)
可以使用kendo组件将页面中一个元素与一个简单独立的业务数据事件类绑定在一起。这样可以更加灵活的变化和使用kendo组件与html页面的元素关系。
在例子中我们在index.ts 视图引导类中初始化一个业务类与页面元素的对应关系,将它们绑定在一起。
kendo 的组件绑定模板中html元素与一个简单的业务逻辑类
import template from './template.hbs';
import ViewModel from './ViewModel';
/**
* 练习入口
*/
export default function initIndex(): ViewWithTitle {
const vm = new ViewModel();
const view = new kendo.View(
template({
name:'DataSource',
}),
{
model: vm,
init:function(){
const viewModel = kendo.observable({
name: '韬哥',
mail: 'zht114001@163.com',
onSaveUp():void {
const name = this.get('name');
const mail = this.get('mail');
alert('Hello, ' + name + ' ' + mail + '!!!');
}
});
//页面元素与viewModel业务逻辑类建立绑定
kendo.bind($('#zhtview'), viewModel);
}
},
);
return { title: 'kendo', view};
}
template.hbs(模板)
------------------------------------------------------
<div id="zhtview">
<label>First Name:<input data-bind="value: name" />
</label>
<label>Last Name:<input data-bind="value: mail" />
</label>
<button data-bind="click: onSaveUp">提交</button>
</div>
kendo 组件内嵌模板template使用(例子15)
kendo 组件提供了一个将模板编译为构建 HTML 的函数,这样为我们开发提供了更加灵活操作性。同时这个模板使用自己的模板语法,也弥补了kendo引入的模板(html页面)时候有些功能和数据读取与操作困难的问题。
模板使用 # = 数据模型引用 # 和 #:数据模型引用 # 这两种方式来加载数据模型中的数据信息内容量 {数据模型引用:‘数据’}。
#if (foo) {# foo is true #}# 使用这种方式进行脚本判断。
export default function initIndex(): ViewWithTitle {
const vm = new ViewModel();
const view = new kendo.View(
template({
name:'DataSource',
}),
{
model: vm,
//初始化方法
init:function(){
$('#zhttemplate1').html(
kendo.template('我读取模板信息: #: html #')
({html:'template初始化成功'}));
$('#zhttemplate2').html(
kendo.template('#if (foo) {# foo is true #}#')
({foo:true}));
}
},
);
return { title: 'kendo', view};
}
例子2
逻辑类中定义模板绑定判断功能。
export default class ViewModel extends kendo.data.ObservableObject {
//构造函数
constructor() {
super();
}
public foo:any;
public istemplate():void{
this.foo=false;//定义为false
$('#zhttemplate2').html(
kendo.
template('#if (foo) {# foo is true #}#')(this));
}
}
template.hbs(模板)
------------------------------------------------------
<div class="mypage">
<h1 id="zhttemplate2"></h1>
<button
data-bind="click:istemplate">zhttemplate2 模板改变</button>
</div>
模板中数组循环遍历
可以在逻辑类中定义数组信息传递到模板中,在模板中循环遍历数组的信息组成html元素的字符串,在将这个字符串传递给对应的html元素。
template 中 # for (var i = 0; i < data.length; i++) { # 模板的循环体 # } #
export default class ViewModel extends kendo.data.ObservableObject {
//template 模板循环内容
public onfor():void{
const data = [{name:'a1',id:1},
{name:'a2',id:2},
{name:'a3',id:3},
{name:'a4',id:4}];
//获得模板数据内容
const template =kendo.template($('#javascriptTemplate').html());
//将模板与数据绑定后生成的html字符串传,在examplezhtbs元素上生成html
$('#examplezhtbs').html(template(data));
}
}
template.hbs(模板)
------------------------------------------------------
<script id="javascriptTemplate" type="text/x-kendo-template">
<ul>
//数组循环
# for (var i = 0; i < data.length; i++) { #
<li>#= data[i].id# ---- #= data[i].name #</li>
# } #
</ul>
</script>
kendo comfirm
和window.comfirm()方法的使用一样,但是需要在comfirm内设函数中定义确认功能。
kendo.confirm("Confirm text")
.done(function(){
//确认部分代码
})
.fail(function(){
//取消部分代码
});
Kendo treeview 树组件(例子15)
kendo提供了tree树型UI主键功能。我们需要使用HierarchicalDataSource 数据源来和treeview 进行mvvm数据绑定与对接。使用data-text-field元素来指定数据结构中对应数据的节点属性名称。
export default class ViewModel extends kendo.data.ObservableObject {
//构造函数
public dataSource1: kendo.data.HierarchicalDataSource;//创建数据源引用
constructor() {
super();
this.dataSource1=new kendo.data.HierarchicalDataSource({
data: [
{ ProductName: '***总公司',ID:1,
items: [
{ ProductName: '第一分公司',ID:10},
{ ProductName: '第二分公司',ID:20,
items: [{ProductName: '第201分公司',ID:2010}]}
] } |
] |
});//创建一个数据源 |
} |
} |
template.hbs(模板) |
-----------------------------------------------------|
<div> |
data-role="treeview" |
data-text-field="['ProductName']" <-------|
data-bind="source: dataSource1">
</div>
树节点事件设置
kendo mvvm模式下需要载模板中定义一个events:{select:onSelet} 事件,我们在逻辑类中定义这个树组件的事件实现。
export default class ViewModel extends kendo.data.ObservableObject {
.........
//树事件
public onSelet(e:any):void{
const treenode:kendo.data.Node//设置树节点选择内容
= $('#zhttreeview').data('kendoTreeView')//kendo 获得树内容
.dataItem(e.node);//获得节点对象内容json对象{}
alert(treenode.get('ID'));//获得json对象内的属性值
}
}
template.hbs(模板)
------------------------------------------------------
<div
id="zhttreeview"
data-role="treeview"
data-text-field="['ProductName']"
data-bind="source: dataSource1,
events:{select:onSelet}">
</div>
2个树联动信息
两个kendo 树组件进行事件联动。定义两个树的数据源A树dataSource1,B树dataSource2,在构造方法中初始化这两个数据源,在模板中定义两个树的组件,分别绑定数据源data-bind="" dataSource1和dataSource2。
通过第一个树的节点点击事件,通过第一个A树的节点内容为dataSource2数据源的绑定不同的数据值,这个时候B树就会根据dataSource2数据源内容的变化而变化。
export default class ViewModel extends kendo.data.ObservableObject {
//构造函数
public dataSource1: kendo.data.HierarchicalDataSource;//创建数据源引用
public dataSource2: kendo.data.HierarchicalDataSource;//创建数据源引用
constructor() {
super();
this.dataSource1=
new kendo.data.HierarchicalDataSource({
data: [
{ ProductName: '***总公司',ID:10,
items: [
{ ProductName: '第一分公司',ID:100},
{ ProductName: '第二分公司',ID:200 ,
items: [{ProductName: '第201分公司',ID:2010 }]}
] }
]
});//创建一个数据源
this.dataSource2=new kendo.data.HierarchicalDataSource({
data: [
{ text: '初始化200', items: [
{ text: '初始化200' }
] }
]
});
}
//树事件
public onSelet(e:any):void{
const treenode:kendo.data.Node= $('#zhttreeview').data('kendoTreeView').dataItem(e.node);
const id=treenode.get('ID')
console.log(e);
if(id==200){
this.dataSource2.data([//树2的数据源加载
{ text: '初始化2220', items: [
{ text: '部门2220' }
] }
]);
}
if(id==100){
this.dataSource2.data([//树2的数据源加载
{ text: '初始化100', items: [
{ text: '部门1000' }
] }
]);
}
if(id==10){
this.dataSource2.data([//树2的数据源加载
{ text: '初始化1', items: [
{ text: '部门1' }
] }
]);
}
}
}
template.hbs(模板)
------------------------------------------------------
<div
id="zhttreeviewb"
data-role="treeview"
data-text-field="['text']"
data-bind="source: dataSource2">
</div>
<div
data-role="treeview"
data-text-field="['DeviceGroupName', 'DeviceName']"
data-bind="source: dataSource">
</div>
其他附件
javaWeb服务类
DataSource使用到的java代发web端的示例代码,我们的web端使用的是spring boot来实现的。如果使用其他语言需要方法web端的rest josn串就可以实现这个示例。
@RestController
public class RestMainController{
@PostMapping("/zhtbs/test")
public List getFind(){
return findlist(null);
}
@PostMapping("/zhtbs/save")
public List save(@RequestBody Map user){
System.out.println("save "+user.get("name"));
return findlist(user);
}
@PostMapping("/zhtbs/up")
public Map up(@RequestBody Map user){
System.out.println("up "+user.get("name")
+" "+user.get("myid"));
return user;
}
@PostMapping("/zhtbs/del")
public Map del(@RequestBody Map user){
System.out.println("delete "+user.get("name")
+" "+user.get("myid"));
return user;
}
@PostMapping("/zhtbs/pagelist")
public Map pagelist(@RequestBody Map user){
System.out.println("page "+user);
List list=findlist(null);
Map pagemape=new HashMap();
pagemape.put("data",list);//内容
pagemape.put("count",5);//总条数
return pagemape;
}
public List findlist(Map user){
List list=new ArrayList();
Map map=new HashMap();
map.put("myid","1");
map.put("name","zht");
list.add(map);
Map map1=new HashMap();
map1.put("myid","2");
map1.put("name","b1");
list.add(map1);
Map map2=new HashMap();
map2.put("myid","3");
map2.put("name","b2");
list.add(map2);
Map map3=new HashMap();
map3.put("myid","4");
map3.put("name","b3");
list.add(map3);
Map map4=new HashMap();
map4.put("myid","5");
map4.put("name","b5");
list.add(map4);
if(user!=null){
list.add(user);
}
return list;
}
}
更多推荐
所有评论(0)