同步操作将从 虫儿飞/vita-plus 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
vita-plus是围绕spring mvc和组件构成的一个异想天开的前端框架,主要体现在开发套路的改变。它集成了多个开源框架和工具包,辅以自主研发的功能,给了开发们一个不一样的体验。同时,vita-plus还实现了一种另类的客户端自适应方式。
写一个html:
<div data-widget="homepage">
这里是<a>首页</a>
<div>这是做一个$options.text</div>
</div>
然后写一个js:
(function(vita){
var homepage = vita.Backbone.BizView.extend({
events : {
"click a" : function(){
this.callService("indexClick", function(txt){
alert(txt);
});
}
}
});
vita.widget.register("homepage", homepage, true);
})(window.vita);
再写一个java:
@Component("vita.homepage")
public class Homepage extends AbstractComponent{
public Map achieveData(Object... params) throws Exception {
Map options = new HashMap();
options.put("text","开发套路");
return options;
}
public String indexClick() throws Exception {
return "您点击了首页!";
}
}
最后写一个controller的服务:
@RequestMapping(value = "homepage")
public String homepage(HttpServletRequest request, Model m) throws Exception {
Map options = achieveData("homepage");
return initView("homepage", "首页", options, m, request);
}
当访问homepage这个服务的时候,浏览器会渲染出:
这里是首页
这是做一个开发套路
当点击首页
时,会alert提示您点击了首页!
。
该框架在js方面,提供了以下能力:
核心
:基础函数实现,核心能力不依赖第三方执行队列
:以生产和消费消息体的方式,实现js函数的执行队列,支持队列分类管理事件侦听
:以发布订阅的方式,实现在对象上的事件侦听,支持事件注册、监听、派发,事件派发处理使用了执行队列
切面
:支持js对象和dom对象的事件/方法切面处理,支持事件前、事件后、事件前后处理ajax
:封装$.ajax以及$.fn.load方法,实现404、500等异常处理,实现统一遮罩等路由
:管理history(不是浏览器的history),可以判断是程序切换,还是前进后退按钮,并且可以限制路由变化组件框架
:js组件框架实现,组件可继承,并且维护组件极组件实例的生命周期(组件注册、注销、实例化、使用、销毁等),实现了js组件基类、js ui组件基类、js backbone组件基类、js biz业务组件基类模块
:js组件模块化封装,隐藏js组件的属性和私有函数,支持与seajs和requirejs模块的相互调用框架提供了以下js功能组件:
util
、objectUtil
、functionUtil
、domUtil
、collectionUtil
、chain
、arrayUtil
模块input
、container
、inlineText
等等,支持主题切换框架提供了两个html布局容器,一个独立访问模块时使用,另一个在流程中使用
框架希望在开发时,所需的资源与路径无关,所以需要将资源加载到内存中
根据访问服务的终端,推送适配终端的模版
通过velocity自定义指令,实现html、js、css资源的按需加载
配置资源与路径无关的目标,实现了一系列的java方法和接口,用来数据处理或者与服务端的数据交互
在pom.xml中做以下依赖:
<dependency>
<groupId>com.ai</groupId>
<artifactId>vita-plus</artifactId>
<version>1.0.8</version>
</dependency>
在spring配置文件中,引入以下xml:
<import resource="classpath:vita-plus.xml"/>
在spring配置文件中,引入以下bean配置,将使用velocity作为视图解析器:
<bean id="velocityConfigurer" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
<property name="resourceLoaderPath" value="/WEB-INF/classes/com/al/crm,classpath:com/ai"/>
<property name="velocityProperties">
<props>
<prop key="input.encoding">utf-8</prop>
<prop key="output.encoding">utf-8</prop>
<prop key="userdirective">com.ai.vita.velocity.directive.WidgetCreate</prop>
</props>
</property>
</bean>
如果已有该配置,则做以下配置:
resourceLoaderPath
属性里增加classpath:com/ai
velocityProperties
增加<prop key="userdirective">com.ai.vita.velocity.directive.WidgetCreate</prop>
com.ai.vita.velocity.directive.WidgetCreate
是自定义velocity指令
该框架的资源取自于内存,所以配置所需资源的加载配置,在spring配置文件中增加以下bean配置:
<bean id="templateLoader" class="com.ai.vita.template.TemplateLoader" init-method="init">
<property name="realTime" value="true"/>
<property name="resourcePaths">
<array>
<value>com/al/crm/superSo</value>
</array>
</property>
<property name="subDirectory" value="true"/>
<property name="filter" value="js,html,css"/>
<property name="minified" value="true"/>
<property name="minifiedExt" value="min"/>
<property name="properties">
<map>
<entry key="scriptType" value="text/javascript"></entry>
</map>
</property>
</bean>
realTime
是boolean类型,表示是否实时更新资源,必须设置resourcePaths
是String[]类型,用来存放所需加载资源的路径,至少指定一个路径subDirectory
是boolean类型,表示是否包含子目录,必须设置filter
是String类型,用来存放资源的过滤,多个过滤使用英文逗号分隔minified
是boolean类型,表示是否使用minified资源minifiedExt
是String类型,用来存放minified资源的标识,如果不设置默认为minproperties
是Map类型,用来存放各种设置属性,目前实现scriptType,用来设置script标签中的type创建一个控制器,继承com.ai.vita.ApplicationController
,在构造函数里设置以下属性:
setAssistContainer("superSo/frame/assistContainer");
setWidgetContainer("superSo/frame/widgetContainer");
setServicePath("../superSo");
setClassifications(MDA.classificationsMap);
setAssistContainer
用来设置界面切换用的布局容器,不设置将使用框架自带的布局容器setWidgetContainer
用来设置模块界面使用的布局容器,不设置将使用框架自带的布局容器setServicePath
用来设置服务路径,将供js组件使用,一般设置成当前控制器的RequestMapping,也可以是其他控制器的RequestMapping,只要是继承了com.ai.vita.ApplicationController
或者com.ai.vita.AbstractController
的控制器都行,不设置将抛出异常setClassifications
用来设置模版分类,可根据终端类型推送设置好的模块模版,不设置则不区分终端,可以设置的key有Computer、Mobile、Tablet以首页为例,模块命名为homgpage:
创建html组件,文件名约定为:homepage-tpl.html
data-widget
标识为依赖的js组件名
创建js组件,文件名约定为:homepage.js
vita.Backbone.BizView
是基于backbone的view封装扩展的一个view基类,所有的js组件都需要继承它来开发
events
是backbone提供的事件侦听配置
backbone提供的组件初始化方法是initialize,该方法被vita用来处理框架逻辑,组件私有初始化方法改为_initialize
vita.widget.register("homepage", homepage, true)
这里是把js组件注册到vita的容器管理,true表示需要生成名为homepage的jquery插件,即增加$.fn.homepage方法,以供jquery对象直接访问组件里的方法
(function(vita){ var homepage = vita.Backbone.BizView.extend({ events : {
},
_initialize : function(){
}
});
vita.widget.register("homepage", homepage, true);
})(window.vita);
创建java组件,文件名约定为:Homepage.java
必须要继承com.ai.vita.AbstractComponent
beanId约定为vita.homepage
必须要实现Map achieveData(Object... params)
,该接口用来组件数据准备,供html组件使用,这个接口供界面入口调用,也可以被其他模块的java组件调用
@Component("vita.homepage") public class Homepage extends AbstractComponent{ public Map achieveData(Object... params) throws Exception { Map options = new HashMap(); return options; } }
在控制器里创建界面入口,RequestMapping约定为homepage
通过achieveData
方法,初始化组件数据,第一个入参是模块名
通过initView方法,处理模版和数据,入参分别为:模块名、显示名称(title)、数据、Model、HttpServletRequest
@RequestMapping(value = "homepage") public String homepage(HttpServletRequest request, Model m) throws Exception { Map options = achieveData("homepage"); return initView("homepage", "首页", options, m, request); }
以上完成了一个完整的模块开发,可以使用
/控制器/homepage
路径进行访问
一个模块开发完,是不能进行界面切换的,需要创建一个流程来实现界面间的切换。
流程,可以认知为,是为了实现某个业务目的的一个模块集合,通过这个模块集合里的模块切换,协同支撑了该业务目的的实现。
以命名为main的流程为例:
创建一个js文件,约定命名为:main-assist.js
assist
是一个变量,将被框架捕捉
prototype
属性,指定一个类的原型,将被框架捕捉,即,只有继承该原型的组件,才会被框架识别
nodes
属性,指定该流程的模块集合
name
属性,指明节点名称,约定为模块名
url
属性,指明节点界面入口,即上节内容里的控制层服务地址
assist
属性,js组件里assist接口的具体实现,用来请求某个模块,来获取并处理数据
end
属性,js组件里end接口的具体实现,用来交出界面控制权
assist
和end
的实现,都需要一个return,其完整的返回值格式为[ [ 目标节点名称 , 参数 , 是否刷新 ] , [ 回调函数 , 回调函数调用对象 ] ]
var assist = { prototype : "vita.Backbone.BizView.prototype", nodes : [ { name : "homepage", url : "../superSo/homepage", assist : function(){ return [["partyQuery", true], function(data){ console.info(data); history.back(); }]; }, end : function(){
}
},
{
name : "partyQuery",
url : "../superSo/partyQuery"
}
]
};
以上完成一个完整的的流程开发,意思是:
vita.Backbone.BizView
的模块homepage
和partyQuery
/控制器/vector?assist=main
进行访问js组件基类分为视图(view)和模型(model)两个,其中视图用来处理各种事件、小部分额外的界面渲染,而模型用来数据处理。
BizView作为所有组件的视图基类,实现了以下方法,在其子组件内部可以通过this调用
refreshPart : 局部刷新,可以指定组件内部的一部分html进行刷新操作
this.refreshPart(methodName, params, selector, keyName, callBack, options);
methodName
指定需要调用的方法,该方法必须在js组件对应的java组件里存在的方法params
指定调用methodName
时送入的参数,类型建议是string或者json,如果需要传递多个入参,则可以将该参数设置为数组,数组长度必须与methodName
的参数个数相同,否则会抛出异常selector
指定选择器,即被刷新部分的容器,比如:"#offer",则被刷新的内容就是id为offer的html对象里面的内容keyName
指定key值,即模版里使用的$options的key,用于模版取值。如果methodName
的返回值是map类型,则该参数无效,可不送入,返回值的key将与$options的key对应,调用可变成this.refreshPart(methodName, params, selector, callBack, options)
;否则没有该参数将抛出异常。callBack
指定回调函数,用于refreshPart
方法返回数据时的处理,该回调函数可通过第一个形参获取到refreshPart
方法的返回数据,如function(re){}
。注意:refreshPart
的返回值是已经拼装完成的html的字符串,可使用$()转成jquery对象。options
指定ajax的参数,参数值参考$.ajax,另外增加了mask属性,用来启用遮罩,如{mask : true}
increasePart : 局部增加,可以指定组件内部的一部分html进行累加操作
this.increasePart(methodName, params, selector, keyName, callBack, options)
methodName
指定需要调用的方法,该方法必须在js组件对应的java组件里存在的方法params
指定调用methodName
时送入的参数,类型建议是string或者json,如果需要传递多个入参,则可以将该参数设置为数组,数组长度必须与methodName
的参数个数相同,否则会抛出异常selector
指定选择器,即被刷新部分的容器,比如:"#offer",则被刷新的内容就是id为offer的html对象里面的内容keyName
指定key值,即模版里使用的$options的key,用于模版取值。如果methodName
的返回值是map类型,则该参数无效,可不送入,返回值的key将与$options的key对应,调用可变成this.increasePart(methodName, params, selector, callBack, options)
;否则没有该参数将抛出异常。callBack
指定回调函数,用于increasePart
方法返回数据时的处理,该回调函数可通过第一个形参获取到increasePart
方法的返回数据,如function(re){}
。注意:increasePart
的返回值是已经拼装完成的html的字符串,可使用$()转成jquery对象。options
指定ajax的参数,参数值参考$.ajax,另外增加了mask属性,用来启用遮罩,如{mask : true}
refreshView : 刷新视图
this.refreshView(params, callBack, options)
params
指定刷新时送入的参数,类型建议是string或者json,如果需要传递多个入参,则可以将该参数设置为数组,数组长度必须与java组件中achieveData
方法的参数个数相同,否则会抛出异常callBack
指定回调函数,用于refreshView
方法返回数据时的处理,该回调函数可通过第一个形参获取到refreshView
方法的返回数据,如function(re){}
。注意:refreshView
的返回值是已经拼装完成的html的字符串,可使用$()转成jquery对象。options
指定ajax的参数,参数值参考$.ajax,另外增加了mask属性,用来启用遮罩,如{mask : true}
callService : 服务访问,仅访问对应的java组件里的服务(js里只能访问java组件里的服务,不允许方法controller,为的是服务与controller解绑,便于模块移植)
this.callService(methodName, params, callBack, options)
methodName
指定需要调用的方法,该方法必须在js组件对应的java组件里存在的方法params
指定刷新时送入的参数,类型建议是string或者json,如果需要传递多个入参,则可以将该参数设置为数组,数组长度必须与java组件中methodName
方法的参数个数相同,否则会抛出异常callBack
指定回调函数,用于callService
方法返回数据时的处理,该回调函数可通过第一个形参获取到callService
方法的返回数据,如function(re){}
。options
指定ajax的参数,参数值参考$.ajax,另外增加了mask属性,用来启用遮罩,如{mask : true}
addListener : 增加侦听,在接收到事件时促发,一般用于不同模块之间的交互
this.addListener(eventName, func)
eventName
指定需要侦听的事件名,在接收到该事件时促发funcfunc
指定促发事件时需要执行的逻辑,可通过形参接收到事件所附加的数据removeListener : 删除侦听
this.removeListener(eventName, func)
eventName
指定需要删除的事件名func
指定需要删除事件逻辑,如果不送,则删除该事件下的所有逻辑dispatchEvent : 事件派发,一般用于不同模块之间的交互
this.dispatchEvent(widget, eventName)
this.dispatchEvent(eventName, data...)
this.dispatchEvent("vita.widgetName", eventName, data...)
this.dispatchEvent("#id1,id2", eventName, data...)
widget
指定接收事件的组件,可不指定;不指定时,所有侦听了eventName
事件的组件都将接收到事件;指定时,可以加vita.前缀标识使用了vita框架的组件,或者可以加#标识组件实例的id,需要指定多个组件时,可以用,分隔eventName
指定事件名,必须指定eventName
后增加参数,作为事件附加数据popup : 弹窗1,用于alert、confirm
this.popup(info, baseFunction, extFunction)
info
指定提示信息baseFunction
指定点击“确定”时的事件extFunction
指定点击“取消”时的事情popup
显示为alert模式;同时存在baseFunction
和extFunction
时,popup
显示为confirm模式dialog : 弹窗2,用于对话框、需要填写内容等
this.dialog(id)
this.dialog(options)
id
指定id,用于打开已经使用id生成过dialog的场景options
指定生成新dialog的参数,是一个json结构,说明如下:options.id
指定dialog的id,可不指定,若指定id并且destroy值为false时,下次可通过id使用该dialogoptions.title
指定dialog的标题,可不指定options.url
指定dialog需要加载的url,优先级比options.content
高options.params
指定dialog加载url时需要传递的参数,为json结构options.content
指定dialog需要加载的内容,优先级比options.url
低options.buttons
指定dialog需要生成的按钮,结构为json或者json数组,可以设置三个属性:class
指定样式,text
指定按钮名称,click
指定按钮事件options.onClose
指定dialog在关闭时需要触发的事件options.onCancel
指定在取消dialog时触发的事件,如dialog自身的“关闭”按钮options.destroy
指定dialog在关闭的时候是否销毁,需是boolean值options.autoClose
指定dialog在触发按钮事件后,是否需要自动关闭窗口,需是boolean值assist : 请求协助,一般用于请求其他模块的数据,类似服务调用;在组件里,只是描述为一个接口,在界面流转时才会有真实逻辑
this.assist(flag, data, callBack)
flag
指定一个描述,用于描述一个需要请求的模块名,该模块名可以真实存在,也可以是虚拟描述data
指定在请求flag
模块时,需要传递的参数,建议为jsoncallBack
指定请求flag
模块后,用来接收flag
模块输出的数据的处理函数,如function(re){}
end : 当前模块逻辑结束描述,一般在明确当前模块的逻辑全部处理完,需要把焦点传递给其他模块时调用,表明当前模块逻辑结束;在组件里,只是描述为一个接口,在界面流转时才会有真实逻辑;
this.end(flag, data, special)
flag
指定一个描述,用于描述下一个接收焦点的模块名,该模块名可以真实存在,也可以是虚拟描述data
指定在移交焦点给flag
模块时,需要传递的参数,建议为jsonspecial
指定特殊处理标识,当前有两类特殊处理,一类是强制移交,值为vita.REDIRECT;另一类是移交给上级界面流转描述,值为vita.OUT_OF_FOCUSrefreshSession : 更新session,用于员工信息、渠道更新(可按需重写)
this.refreshSession(session)
session
指定要更新的session值,json类型removeSession : 清除session(可按需重写)
this.removeSession()
refreshParty : 更新session中的客户信息(可按需重写)
this.refreshParty(party, reset)
party
指定要更新的party值,json类型reset
指定是否需要重置,重置会清除原有全部信息,再用party
赋值,如果不重置,只会重置party
里有的值,其余值保留removeParty : 清除session中的客户信息(可按需重写)
this.removeParty()
BizModel作为所有组件的模型基类,暂无扩展
html组件上提供的能力主要分为两类:一类是velocity自定义指令;一类是html自定义标签
html组件里统一的取数据入口,所有送到html组件的数据,统一由$options取出
$options.offerSpec
velocity自定义指令,在html里引用组件,可以加载html组件、对应的js组件、对应的本地js组件、对应的css,实现按需加载
#widgetCreate(widgetName, data)
widgetName
指定要加载的模块名称data
指定传递给widgetName
的数据html自定义标签,提供数据附加能力,将该标签里的数据,附加到指定的html对象上,再通过jquery的data方法取出使用
<input type="text" id="test">
<vita-data for="test">{"partyId":123456}</vita-data>
for
属性指定html对象的id,即把标签内的数据附加到指定id的html对象上
data
指定附加的数据,建议为json,如果是json,则附加到html对象上的key将等同与json里的key;如果不是json,会将数据以vita-data
为key,附加到html对象上;上例中调用$("#test").data("partyId") => 123456
没有指定for
属性时,优先将该标签的前一个标签作为附加数据的html对象
data
指定附加的数据,建议为json,如果是json,则附加到html对象上的key将等同与json里的key;如果不是json,会将数据以vita-data
为key,附加到html对象上;上例中调用$("#test").data("vita-data") => 123456
for
属性时,并且没有前一个标签时,将该标签的父级标签作为附加数据的html对象data
指定附加的数据,建议为json,如果是json,则附加到html对象上的key将等同与json里的key;如果不是json,会将数据以vita-data
为key,附加到html对象上;上例中调用$("#test").data("partyId") => 123456html自定义标签,提供数据绑定能力,将指定的html对象与js组件里的model做绑定,并且将标签内的数据作为默认值。model值变化时将作用到html对象,html对象值变化时将作用到model。
<input type="text" id="test">
<vita-bind for="test" action="input" mapper="value" model="data">123456</vita-bind>
for
属性指定与model绑定的html对象的id
mapper
属性指定与model绑定的html属性
model
属性指定与model绑定的key
action
属性指定一个html事件,在该事件触发时,去改变model
data
指定默认值,可不指定
上述标签描述为:将#test(for
)对象的value(mapper
)属性,在触发input(action
)事件时,写入到js组件model的data(model
)里;在js组件的model的data(model
)值被改变时,将改变后的值,写到#test(for
)对象的value(mapper
)属性;123456(data
)作为data(model
)和value(mapper
)的默认值
没有指定for
属性时,优先将该标签的前一个标签作为附加数据的html对象
没有指定action
属性时,默认为输入事件,一般情况下,输入事件禁止显式设置,因为设置成input会有IE8的兼容性问题,不设置的话,框架会做兼容性处理
没有指定mapper
属性时,如果html对象是输入型的,框架将默认为value;如果是不可输入型的,框架将默认成html
model
必须设置,不设置该标签无效
for
属性时,并且没有前一个标签时,将该标签的父级标签作为附加数据的html对象action
属性时,默认为输入事件,一般情况下,输入事件禁止显式设置,因为设置成input会有IE8的兼容性问题,不设置的话,框架会做兼容性处理mapper
属性时,如果html对象是输入型的,框架将默认为value;如果是不可输入型的,框架将默认成htmlmodel
必须设置,不设置该标签无效此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。