SG-UAP_V3 0 0_高级开发手册_分册8 微服务前端展现框架MVVM_第1页
SG-UAP_V3 0 0_高级开发手册_分册8 微服务前端展现框架MVVM_第2页
SG-UAP_V3 0 0_高级开发手册_分册8 微服务前端展现框架MVVM_第3页
SG-UAP_V3 0 0_高级开发手册_分册8 微服务前端展现框架MVVM_第4页
SG-UAP_V3 0 0_高级开发手册_分册8 微服务前端展现框架MVVM_第5页
已阅读5页,还剩113页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

SG-UAP高级开发手册-客户端开发(MVVM)国家电网公司应用系统统一开发平台微服务前端展现框架(MVVM)国网信息通信产业集团研发中心2017年2月目录SG-UAP业务系统之前端篇51.1MVVM展现框架概述51.1.1概述51.1.2技术储备声明式绑定属性监控与依赖跟踪控制文本和外观的绑定控制流绑定控件绑定141.1.3结构概览151.1.4开始使用151.1.5配置参数201.1.6数据控件和服务端的交互数据规约221.2MVVM展现框架开发261.2.1基础类2基础类概述2基础类的开发及应用(类图)2.1CUBE类261.2.2国际化2.1国际化的构成2.2脚本文件2国际化运行机制2国际化开发及应用2.1资源管理2.2国际语言切换291.2.3控件2控件的使用方法2基础类控件30.1标签控件(cubelabel)30.2按钮控件(cubebutton)3.3日期控件(calendar)3.4菜单控件(menu)3.5导航条控件(navbar)3.6工具条控件(toolbar)3.7面包屑控件(breadcrumb)3.8右键菜单控件(contextmenu)3.9进度条控件(progressbar)4.10幻灯片控件(carousel)4布局类控件4.1列式布局(columntypelayout)4.2表格式布局(gridlayout)4.3流式布局(fluidlayout)4.4Border布局(borderlayout)4.5页面引入(include)50容器类控件5.1选项卡控件(tabcontrol)5.2手风琴容器控件(accordion)5.3面板控件(panelcontainer)5.4水平分割控件(hsplit)5.5垂直分割控件(vsplit)5数据类控件6.1表单控件(dataform)6.2表格控件(datagrid)6.3多表头表格控件(groupheadergrid)6.4分页控件(pagenavibar)7.5树控件(tree)7窗体类控件7.1模态对话框(modaldialog)7.2消息对话框(msgdialog)7.3消息弹出框(popoverdialog)7编辑器类控件7.1通用编辑器(commoneditor)7.2文本编辑器(TextEditor)7.3复选框(CheckEditor)7.4组合单选/复选(CheckListEditor)80.5下拉列表(DropDownEditor)8.6列表编辑器(ListEditor)8.7数字编辑器(NumberEditor)8.8日期时间选择(datetimeeditor)8.9文件上传编辑器(fileeditor)8.10图片编辑器(imageeditor)8.11富文本编辑器(richeditor)8图形类控件8工具类控件9.1REST服务客户端(RESTClient)9.2验证字符串(CheckUtil)9.3GUID字符串(GUIDUtil)9.4Json工具(JSONUtil)941.3MVVM展现框架高级特性961.3.1监控属性订阅961.3.2订阅发布机制961.3.3路由机制971.3.4页面跳转及传参981.3.5自定义控件9创建自定义控件9自定义控件的使用1031.3.6自定义主题样式10新建及修改样式10样式调试及使用1041.4MVVM展现框架配置参考10Bootstrap Less 变量及其默认值10Cube Less 变量及其默认值10build.xml文件内容1121.5其他注意事项1关于IE9及以下版本跨域问题1框架资源文件无法加载问题1自定义控件或主题无效问题115SG-UAP业务系统之前端篇1.1 MVVM展现框架概述1.1.1 概述MVVM模式作为框架核心,包含以下三个部分:l Model: 模型,业务数据,表示业务中的对象和操作,和view独立。l ViewModel: 视图模型,对数据和UI操作,就是与界面(view)对应的Model。l View: 视图,可视化、交互式UI。代表了ViewModel的状态,显示ViewModel的内容。图表1 MVVM模式示意图 具体来说,Model仅仅关注数据信息,不关心任何视图操作行为;其不格式化数据或者影响数据在浏览器中的展现,这些都不是它的责任;格式化数据是View层的任务,同时业务逻辑层被封装在ViewModel中,用来和Model进行交互。View是指应用中和用户直接交互的部分,他是一个交互式的UI来表示ViewModel的状态,View被认为是主动的,而不是被动的,MVVM主动式的View包含数据绑定事件和理解Model和ViewModel的行为,尽管这些行为可以和属性对应,但View仍然需要响应ViewModel的事件,同时View不负责控制状态。ViewModel是一个专门用于数据转换的Controller,它可以把Model中的信息转换为View中的信息,同时从View传递命令给Model; 综上,MVVM有以下优点:l MVVM使开发更加容易,使前端开发和后端开发人员互不影响。l 抽象化View层,减少了代码中的业务逻辑。l ViewModel比事件驱动更容易测试。l ViewModel的测试不用关心UI的自动化和交互 。分类选型原则技术选型1、 采用Ajax技术路线;2、 支持HTML4、css2.0以上;3、 支持REST服务调用;4、支持IE8及以上版本,Chrome10以上版本以及firefox3.5及以上版本。开源软件Jquery1.11.1, KnockoutJS 3.2.0 ,bootstrap 2.3.2, RequireJS 2.1.15KnockoutJS是一个轻量级的MVVM框架,通过简易的UI绑定语法,实现动态更新UI。KnockoutJS的特点:l 声明式绑定:通过简洁易读的data-bind语法,将DOM元素与ViewModel关联起来。l UI自动更新:当模型(ViewModel)状态更新时,自动更新UI界面。l 依赖跟踪:在模型数据间建立隐式的关系链。l 模板化:快速生成复杂,可嵌套UI模型数据的函数。l 支持所有主流浏览器,IE 7+,Firefox 2+,Chrome,Opera,Safari (desktop/mobile)。l 无其他依赖。基于KnockoutJS实现模型、视图和视图模型的基础模型框架,满足View和Model分离的需求,两者通过ViewModel联系,并实现视图模型和视图双向绑定功能,视图的变更引起视图模型的变化,视图模型的更改引起视图的更新。Bootstrap是一个Web应用程序的前端工具包。它是一个CSS和HTML的集合,使用了最新的浏览器技术,为Web开发提供了时尚的版式、表单、按钮,表格,网格系统等。利用BootStrap V2.0快速实现前端控件的展示UI。通过Ajax与服务端进行数据交互。通过RequireJS实现对第三方库和js资源的引用,RequireJS 是一个JavaScript 模块载入框架,是 AMD 规范的实现者之一。它使用了不同于传统标签的脚本加载步骤。可以用它来加速、优化代码,其主要目的是为了代码的模块化。例如,可以用RequireJS定义一个模块:define(logger, function(logger) return /功能代码 );用RequireJS加载一个模块:require(jquery, function ($) /jQuery被加载之后就可以使用了);1.1.2 技术储备 声明式绑定Knockoutjs的绑定系统为提供了非常强大且简洁的方式将数据和UI连接起来,可以非常方便的使用这个绑定语法来进行数据的展示。绑定语法:或一个绑定语法由两部分组成:绑定的名字和值,他们之间使用“:”进行隔开。myMessage在viewModel中声明。 属性监控与依赖跟踪观察者变量(Observable),是实现自动更新的方式。通过将viewModel和页面元素绑定的某个变量定义为cube.obj或cube.array,则当viewModel中该变量的值改变,页面对应的元素将自动更新。示例:View中:修改值ViewModel中:define(, function() var PageViewModel = function(params) var self = this;self.content = cube.obj(要显示的内容);self.setContent = function()self.content(修改后的内容);return PageViewModel;);当动态修改self.content的值时,view中的显示文本将自动更新。比如通过View中的一个按钮修改self.content的值。注意:观察者变量赋值时通过调用变量方法进行,比如:self.content(修改后的内容);如果使用等号赋值,该观察者变量将会中断观察,比如:self.content = 修改后的内容;或者self.content = cube.obj(修改后的内容);获取变量值通过变量方法:比如:var contentValue = self.content();观察者变量可以作为参数传递传递到其他ViewModel中,当该变量值在其中一个ViewModel中被修改时,那该观察者变量的值将都会被修改。当变量定义为cube.array时,比如:self.content = cube.array(“河北”,”北京”,”天津”);则会监控数组元素的变化,包括数组元素的新增、删除、排序。观察者数组常用的方法如下:(1)、self.content.push(Some new value):增加一个新的元素。(2)、self.content.pop():删除一个元素,并返回其值。(3)、self.content.unshift(Some new value):在数组的开始处增加一个新的元素。(4)、self.content.shift():删除数组的第一个元素,并返回其值。(5)、self.content.reverse():反转数组的顺序。(6)、self.content.remove(someItem) 移除self.content数组内所有匹配someItem的对象, 并把这些对象组成一个数组返回。(7)、self.content.remove(function(item) return item.age 18 ) 移除self.content数组内所有年龄属性小于18的对象,并返回这些对象组成的新数组。(8)、self.content.removeAll(Chad, 132, undefined) 移除self.content数组内所有匹配Chad,123, undefined 的对象并把它们组成新数组返回。(9)、self.content.removeAll() 移除self.content数组内所有数据,并返回这些数据组成的一个新数组。 控制文本和外观的绑定1) visible绑定通过绑定一个值来确定DOM元素显示或隐藏。示例:View中:这里的内容根据shouldShowMessage的值决定是否显示。修改值ViewModel中:define(, function() var PageViewModel = function(params) var self = this;self.shouldShowMessage = cube.obj(true);self.setShouldShowMessage = function()if(self.shouldShowMessage()self.shouldShowMessage(false);elseself.shouldShowMessage(true);return PageViewModel;);2) text绑定主要是让DOM元素显示参数值。参看章节。3) html绑定到DOM元素上,使得该元素显示的HTML值为绑定的参数。与text的区别为text显示为文本内容,html可以作为HTML标记进行渲染。4) css绑定是添加或删除一个或多个CSS class到DOM元素上。示例:View中: 内容ViewModel中:define(, function() var PageViewModel = function(params) var self = this;self.isHide = cube.obj(true);return PageViewModel;);5) style绑定是添加或删除一个或多个DOM元素上的style值。示例:View中: 内容ViewModel中:define(, function() var PageViewModel = function(params) var self = this;self.width = cube.obj(100px);return PageViewModel;);6) attr 绑定提供了一种方式可以设置DOM元素的任何属性值。示例:View中:ViewModel中:define(, function() var PageViewModel = function(params) var self = this;self.route = cube.obj(#main);return PageViewModel;); 控制流绑定1) foreach:循环遍历输出某个数组、集合中的内容示例:View中:ViewModel中:define(, function() var PageViewModel = function(params) var self = this;self.columns = cube.array( id: 1,caption: 第一列, id: 2,caption: 第二列,id: 3,caption: 第三列,);return PageViewModel;);2) if:条件判断,条件为真时执行示例:View中: ViewModel中:define(, function() var PageViewModel = function(params) var self = this;self.isShowText = cube.obj(true);self.content = cube.obj(显示内容);return PageViewModel;);3) ifnot:条件判断,条件为不为真时执行示例:View中:ViewModel中:define(, function() var PageViewModel = function(params) var self = this;self.isShowText = cube.obj(false);self.content = cube.obj(显示内容);return PageViewModel;); 控件绑定在框架中提供的控件和业务项目中的页面(view和viewModel组合)都为knockout控件。1) 使用框架控件示例: 标签方式:声明绑定方式:说明:l datagrid要使用的控件的名称l params传递给控件的参数,其中的参数key已在控件中定义,可查看控件API。2) 引入项目页面示例:说明:l name页面路径,参照章节1.1.3结构概览,demo.main.main中最后一个main为页面名称(不含view.html和viewmodel.js部分)。l params传递给页面viewModel的参数,通过viewmodel的params参数接受。1.1.3 结构概览图表:结构概览如上图所示:index.html为入口文件,在其中加载框架js文件;model.js中引入app.js文件并进行页面绑定,开始进行展现;app.js中进行所需框架控件的注册;pages目录下为页面文件,其中view和viewmodel成对出现。注意:pages目录必须存在,model.js和app.js可合并为一个文件。 在UAP项目中app_demo放置在模块项目的face目录下。1.1.4 开始使用代码结构参看章节1.1.4。1. 新建入口文件index.html;2. index.html中首先加载框架framework.js,加载app.js。然后通过require.js加载model.js。3. model.js中通过cube.startWebPage方法开始页面绑定并进行页面展示。define(sammy, JSONUtil, entityContainer, function(sammy, jsonUtil, entityContainerClass) entityContainerCtotype.parseData = function(p_result) var me = this;if (me.type = form) if (cube.isEmpty(p_result) | cube.isEmpty(p_result.items) me.data = ; else if (cube.isArray(p_result.items) / 表单只有一条数据,而规约中返回的结果是数组。 me.data = p_result.items0; else me.data = p_result.items; if (cube.isEmpty(me.data) me.data = new Object(); if (cube.isEmpty(me.datame.primaryKey) / 没有主键值,新增状态。 var newPk = guidUtil.newGUID(); me.datame.primaryKey = newPk; / 创建变更记录对象。 me._changedItemsnewPk = new Object(); me._changedItemsnewPk.mxVirtualId = newPk; else / 如果是复合对象,则需把对象扁平化。 me.data = me._getJsonFlatter().jsonFlat(me.data);/ 扁平化结果是数组结构,取其中惟一的扁平化对象。 me.data = me.data0; else me.data = me._getJsonFlatter().jsonFlat(p_result.items);var PageViewModel = function() var self = this;var pvm = new PageViewModel();$(document).ready(function(e)cube.startWebPage(pvm);););4. app.js中声明全局变量和注册页面所用的控件;cube.gatewayURL = http:/localhost:809;cube.ieCorsProxy = true;cube.importComponent(layout.include);cube.importComponent(layout.borderlayout);cube.importComponent(container.tabcontainer);cube.importComponent(datacontainer.tree);cube.importComponent(datacontainer.datagrid);cube.importComponent(datacontainer.dataform);cube.importComponent(datacontainer.pagenavibar);cube.importComponent(datacontainer.searchbox);cube.importComponent(controls.toolbar);cube.importComponent(controls.navbar);cube.importComponent(controls.cubebutton);5. 页面加载在index.html入口文件中可直接组织页面结构,同时也可引入其他页面内容,示例: 缺陷管理系统 jQuery.support.cors=true; 说明:l name页面路径,参照章节1.1.3结构概览,demo.main.main中最后一个main为页面名称(不含view.html和viewmodel.js部分)。l params传递给页面viewModel的参数,通过viewmodel的params参数接受。除入口页面外,pages目录下的页面以view和viewmodel方式成对出现,其中view为html文件,进行页面结构的组织,文件命名方式为xxxview.html;xxxviewmodel为js文件,进行view中使用js变量的声明,文件命名方式为xxxviewmodel.js。viewmodel的代码结构如下:define(, function() var PageViewModel = function(params) var self = this; /逻辑代码cube.endViewModel(self, params);return PageViewModel;);示例:mainview.htmlmainviewmode.js/页面视图模型绑定的数据内容define(, function() var PageViewModel = function(params) var self = this;self.items = text : 缺陷管理,value: demo,hasChildren : false, text : 产品管理,value: product,hasChildren : false, text : 模块管理,value: module,hasChildren : false, text : 项目管理,value: project,hasChildren : false cube.endViewModel(self, params);return PageViewModel;);6. 在页面中使用控件框架提供的控件有两种使用方式:标签方式和声明式绑定方式。只有当页面引用该控件时,才会加载控件资源,如果只是注册了控件,但是页面未使用,并不会加载资源,这就实现了资源按需加载的功能。以表格控件为例:标签方式:声明绑定方式:说明:l datagrid要使用的控件的名称l params传递给控件的参数,其中的参数key已在控件中定义,可查看控件API1.1.5 配置参数由于cube对象为全局js对象,所以以下参数可配置在引入的全局js文件中。例如之前章节中提到的model.js、app.jsl #前端展现框架是否使用调试模式,默认为 true,生产环境下建议设置为 false,当使用非调试模式时将加载压缩过的框架文件,同时也会加载项目中的压缩过的min js文件:cube.debugMode =true注:1、当在入口页面引入framework.min.js时将自动使用非调试模式。例:2、项目中的压缩js需通过编译生成,编译方式为:在build.xml文件上右键Run As Ant Build。build.xml文件内容可参考章节该操作将会为每个viewmodel js生成对应的min js。l #前端展现框架是否使用友好模式(不显示具体报错信息)处理报错,支持三种错误处理方式:#1、正常报错(normal)、2、友好报错(friendly),3:不报错,浏览器控制台日志显示(console)#建议生产模式下调成 console 模式cube.errorType= “normal”l #指定框架的国际化信息。cube. locale = “zh_CN”l #指定模块项目名称,UAP项目中需设置,微服务项目中可不设置。cube. bundleName = “uapmodule”l #指定场景名称。该参数影响cube.mappath的返回值。cube. name = “app_demo”1.1.6 数据控件和服务端的交互数据规约展现框架中的数据控件使用数据视图容器和服务端进行交互。数据实体容器中的url属性描述了REST 风格的数据服务路径定义,该定义是对数据进行查询请求的路径,也是对数据进行编辑请求的基础路径,数据实体容器在对数据进行编辑请求时,会自动在url后面拼接上相应的操作关键字,如下表所示。元数据请求操作的请求url: baseUrl+”/meta”保存操作的请求url: url+”/save”删除服务的请求url: url+”/delete”新增不会产生服务请求,展现框架的新增是数据实体容器根据元数据的定义,在客户端创建一个数据模型对象,在触发数据实体容器的保存时请求保存操作的url进行创建或更新。数据请求操作的返回值都是一个JSON对象,通用的封装格式为:successful:true,resultValue:,resultHint:,errorPage:,type:注:successful:表示服务端处理是否成功;resultValue:表示返回值;resultHint:表示错误提示。errorPage:表示错误自定义页面路径,如果有自定义路径,浏览器会弹出该页面,页面中需要定义“ ”,框架会自动添加页面可关闭的图标。type表示不成功时的类型,可以是info、warn或error,客户端控件会根据type进行提示或报错处理。表单、表格数据实体容器的数据请求操作的返回值的通用封装格式为:successful:true,resultValue: items:,itemCount:10, dicts:name:fieldName,values:value:0,text:xx电力公司,value:1,text:yy电力公司,resultHint:,errorPage:,type:注:items 表示服务端返回的数据实体对象集合,itemCount表示集合长度,dicts表示字典集合信息。表格中的列或表单中的域如果显示值和提交值不一致,则需要通过dicts进行转换。以企业部门的数据操作为例,数据表格和数据表单控件及继承自它们的子控件的数据规约定义如下表:接口名称接口描述获取企业部门指定列的元数据信息URL /rest/department/meta (meta为控件自动添加) 输入参数params:columns:“bmmc”,“bmms”,”sjbm”返回值successful:true,resultValue:columns:name:” bmmc”, (必须)caption:”部门名称”, (必须)nullable:false, (必须)dataType:”string”, (必须)length:”32”, (必须)precision:”,(可选)readOnly:false, (必须)editorType:”TextBox”(可选), name:” bmms”, caption:”部门描述”, , / 第二列 name:” sjbm”, caption:”上级部门”, / 第三列获取企业部门列表URL/rest/department/输入参数params:filter:”, (可选 )/具体使用可参考.8sorter:”MC ASC, BIRTH DESC”(可选 )/数据库排序条件pageIndex:”, (可选)/第几页pageSize:”, (可选)/每页几条columns: “bmmc, bmms, sjbm”/请求哪些列数据返回值successful:true,resultValue:itemCount:100, (必须)items:bmbh: ”xxxxxxxxxxxxxxx”, bmmc:”张三”, sjbm:”男” ,/ 第一个人员数据xxxx,/ 第二个企业部门对象.获取单个企业部门信息URL/rest/ department /bmbh (bmbh是主键值,通过控件自动添加)输入参数columns: “bmbh, bmmc, sjbm”返回值items:bmbh: ”xxxxxxxxxxxxxxx”, bmmc:”上海电力公司”, sjbm:”xxxxxxxxxxx” 保存企业部门信息URL/rest/ department /save (save通过控件自动添加)输入参数items:bmbh: ”xxxxxxxxxxxxxxx”, bmmc:” 上海电力公司”, sjbm:”xxxxxxxxxxx” ,/ 第一个人员数据xxxx,/ 第二个部门数据.说明:如果bmbh为空值,执行新增操作,否则执行更新操作。参数需要在脚本中执行JSON.stringify()进行转换处理。返回值successful:true,resultValue:items:bmbh: ”xxxxxxxxxxxxxxx”, bmmc:” 上海电力公司”, sjbm:”xxxxxxxxxxx” ,/ 第一个部门数据xxxx,/ 第二个部门数据 .删除企业部门信息URL/rest/ department /delete (delete通过控件自动添加)输入参数 ids: ”xxxxxxx001”, ”xxxxxxx002”, /待删除数据主键值数组说明:参数需要在脚本中执行JSON.stringify()进行转换处理。返回值通用返回值对象successful:true,resultValue:以企业部门的数据操作为例,数据树(tree)控件的规约:接口名称接口描述获取第一层企业部门节点信息URL /rest/department/tree/输入参数返回值successful:true,resultValue:nodes:id:”bmbh_001”, (必须,业务唯一标识)text:”江苏省电力公司”, (必须)imageUrl:”,(可选)hasChildren:true,(必须)dataType:” department”获取企业部门子节点信息URL/rest/department/tree/id

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论