• WeX5学习笔记


    目录

    WeX5学习笔记... 1

    1.轻松看透WeX5产品能力和技术... 1

    2.WeX5可以怎么玩?... 3

    一、纯本地App. 3

    二、关联一个网站,希望默认就打开某页... 4

    三、UI设计器... 4

    四、打包神器... 4

    五、标准玩法... 4

    3.WeX5 App与服务端交互原理... 4

    4.Account示例程序... 5

    5.Takeout示例程序... 7

    5.1Index.w.. 7

    5.2mapActivity.w.. 13

    问题... 13

    6.页面间交互视频... 15

    6.1 页面打开和传参概述... 15

    6.2 Shell打开页面... 18

    6.3 对话框与数据传递... 19

    6.4 内嵌页面与参数传递... 21

    7.页面结构及生命周期视频... 23

    课程记录... 24

    1.最简单的应用... 24

    2.firstSPA.. 24

    3.todoMVC.. 24

    4.通过list显示服务端json文件中的数据... 24

    表单与data组件的绑定... 25

    5.实现单表的CRUD.. 25

    6.自己框架实现后台服务... 25

    7. 自己框架集成BaaS代码... 26

    8. WebSocket通信应用... 26

    9.播放音频视频... 26

    10.调试... 26

     

    WeX5学习笔记

    1.轻松看透WeX5产品能力和技术

    首先,必须理解一件事:移动和云时代的企业应用技术,说白了,也就三块:前端UI、后端服务、前端设备api。这后面,是一个事实和趋势:就是前后端已经分化,并各自独立发展:

    1.前端UI

    互联网和浏览器已经普及和扎根,企业应用的前端UI和样式组件,都会沿着w3c的html+css+js路线发展,资源也越来越多,比如bootstrap等。已经没有任何企业,能离开w3c的html+css+js标准,另起炉灶搞自己的了。微软试了不行,adobe试了不行,没人能行。

    2 后服务端

    后端和前端正好相反,技术正走向多元化。node,Python,java并存,以及PAAS、BAAS(后端即服务:Backendas a Service 公司为移动应用开发者提供整合云后端的边界服务)云服务的成熟,数据绑定也要支持多种技术和方向。

    3 前端设备api

    移动和设备在急剧发展,各种硬件能力会更多的加入,想想可穿戴设备吧,想想智能客厅吧,想想未来的手机吧。。。

    总结起来,就是一条原则:“让UI界面归UI界面,让设备api归设备api,让后端服务归后端服务”。仅此而已!

    这个原则,正是WeX5技术设计坚定遵循的原则。正是对这一原则的坚决遵循,才使得WeX5的技术如此开放强大。

    而WeX5另一个强大的原因,是源于开源的力量。免费诚可贵,自由价更高。开源给你的,就是自由。开源是王道啊。

    下面逐条说说WeX5强大之处,以及原因:

    1.开源模式

    WeX5采用的是Apache许可证开源模式,商业友好,完全免费。开发出来的应用,每一行代码都在你手里,发布部署无任何限制,自由,免费。

    2.跨平台多前端应用开发,支持app、web和微信应用快速开发

    WeX5对跨平台多前端应用开发的支持极好,一次开发,多平台运行。

    目前,WeX5能开发的跨平台多前端应用有:

    移动app(苹果ios app、安卓Androidapp)

    微信应用(包括公众号、服务号和企业号应用)

    企业web app(PC、平板和手机)

    其他轻应用(百度直达号等)

    (在企业应用市场,多平台、跨前端已成必须,而非可选!微信应用,已经势不可挡,必将颠覆移动应用的版图。在微信应用和百度直达号等轻应用的推动下,在企业移动应用领域,hybrid app也将固化其主流地位,毫无悬念)

    3.高效精致的UI组件体系,完全基于主流标准和技术

     WeX5的UI组件体系是完全基于html5+css3+js,非常干净标准。

     WeX5的UI组件技术完全是开放主流,基于jquery和bootstrap(Bootstrap是Twitter推出的一个用于前端开发的开源工具包)技术,经WeX5高度优化,在移动上的表现很好,接近原生,真的很赞。

    WeX5 的UI基于模块化开发,采用增强的RequireJS模块化技术

    可视化拖拽设计的组件技术,WeX5已经提供了大量丰富的UI组件,并且支持引入和扩展第三方组件,大大提升了界面开发的效率和降低了难度

    风格样式库基于bootstrap技术,在bootstrap基础上大大增强了适合移动的样式和组件,可轻松引入bootstrap大量丰富的样式资源并随意换肤

    高效灵活的双向数据绑定技术和数据组件,使用简单能力强大

    高度优化,性能接近原生。操作爽滑,拖拽、转场及动画效果很好

    (我个人很认同WeX5的做法,第一,凡是业界主流的好轮子,比如jquery和bootstrap,就应该直接用,而且,WeX5做了深度优化,使app运行效果媲美原生。第二,我有技术洁癖,UI组件库,必须基于html5+css3+js这样的标准,这也是w3c统治互联网的三大基石,没的其它选择啊)

    4.  本机API框架(Native APIFramework)

    WeX5采用混合应用(hybrid app)开发模式。能轻松调用手机设备的系统和硬件能力,如相机、地图、LBS定位、指南针、通讯录、文件、语音、电池。。。等。

    这方面,phonegap/cordova几乎是事实的标准了,很多大公司都采用。在本机框架上,WeX5有:

    基于phonegap(cordova)框架

    默认内嵌高性能浏览器,大大提升性能,特别是android低端机

    提供微信等轻应用框架

    提供了丰富的原生插件

    支持引入和扩展第三方插件,任何原生app能实现的能力都可通过扩展插件实现

    5.  可视化拖拽式集成开发环境IDE

    WeX5的IDE基于eclipse,WeX5的主要工作是强化了可视化快速开发。提供了一个完全可视化、组件化、拖拽式开发环境。

    基于eclipse开源IDE

    可视化、组件化拖拽设计,完全所见即所得

    向导化、模版化等工具,快速生成常见应用场景界面

    全方位代码智能提示,这方面WeX5做了很多功夫,WeX5所有的UI组件,乃至手机本机插件API,在WeX5的IDE里,都能实现代码智能提示,给开发者提供极大方便

    6.  全能力的调试支持和智能代码提示

    开发手机app,模拟调试是关键能力,对开发者极端重要,而这也是业界现有hybrid app开发工具的软肋。WeX5对hybrid app开发提供了业界最强大的调试支持,表现真正完美。

    提供全能力、一站集成的模拟调试支持。开发手机app,日常的调试几乎都是模拟调试,使用频繁度远超真机调试,WeX5提供全面、完备的模拟调试支持,表现真正完美

    WeX5的模拟调试效果和真机运行效果几乎完全相同。由于WeX5的UI组件体系彻底基于html+css+js,并采用高仿真本机设备app模拟,模拟调试运行效果和真机运行效果几乎完全相同,杜绝模拟运行和真机运行不一致的问题

    WeX5开放了所有的UI框架和组件源码,使得开发者能在浏览器里跟踪进入每一个组件的每一行代码,找到和排查到真正的底层原因,系统调试彻底透明,无黑盒,无死角!

    支持真机调试,提供全真机和快捷真机调试模式,为开发者提供最大方便。

    WeX5开放了全部原生app框架源码和本机api插件源码,开发者可以在原生开发环境(Android ADT和XCode)内,跟踪调试进入app的每一行代码里

    7.  无限制、多方式、可加密的App应用打包发布

    WeX5采用Apache 许可证开源协议,商业友好。而且,在开放性上,也走的极端彻底,这一点在app应用打包上得到充分体现:

    打包发布无任何限制,无需任何费用。WeX5彻底开源,应用的每一行代码都在你手里,自由打包,无拘无束!

    轻松打包发布成高性能的原生app,包括安卓Android的apk,苹果ios的ipa

    一键发布微信应用(微信公众号、服务号、企业号均可)

    一键发布成百度轻应用、web应用等

    WeX5打包发布的app和应用,支持全部web资源(html+css+js)的加密,WeX5采用高强度动态密钥,每个app每次编译都会采用不同的动态密钥,真正做到一包一秘!

    支持本地快捷打包、远程服务打包、原生环境编译打包等模式,给你所有想要的打包方式和方便性

    彻底开源,支持原生代码调整、插件自定义和插件选择打包,真正自由

    8.彻底开放的App应用后端技术和部署方式

    WeX5坚决走开源、开放的道路,WeX5在支持后端技术、后端部署上,体现出极端彻底的开放性。

    开放的后端技术支持,WeX5的后端完全开放,可通过http、Websocket等协议连接各种后端中间件或云服务(java、node、php、.net等)

    无限制的后端部署,可以部署在任何自己选择的公有云、私有云服务器上,WeX5的部署完全开放自由,无任何限制

    总而言之,WeX5是多平台、跨前端应用开发的优秀工具,业界收费的同类工具,和WeX5相比,技术要落后和老化不少。最难得的是:WeX5采用商业友好的Apache许可证开源模式,用的放心啊。

    企业移动应用大潮滚滚,微信应用扑面而来,祝各位朋友用好开源的WeX5,多多发财!

    2.WeX5可以怎么玩?

    一、纯本地App

    没任何服务请求,已经有开发好的一堆html+js,希望本地App中可以方便的使用,那可以参考默认的Native/X5工程,把自己开发好的资源放到www目录下就可以,注意工程的几个重要选项:

    服务地址:http://localhost

    首页: 假设你www中有一个入口的index.html,那写 /index.html

    生成App包的向导中,“重新编译使用到的UI资源”一定不要选

    二、关联一个网站,希望默认就打开某页

    例如想把本论坛做成一个app,那可以新建一个本地App,把

    服务地址:http://bbs.justep.com

    首页: /forum.php

     这样生成的app,一启动就打开论坛的首页

    三、UI设计器

    UI2下建自己应用(例如demo),形成自己的一组页面,然后Native新建一个本地App,选择新建的资源demo,点右键“编译使用到的UI资源”,则在ww下生成标准的html+js,该资源可以放到标准 web 服务器(apache, iis, tomcat等)直接进行网络访问

    四、打包神器

    什么UI2,什么X5不要,我就只要一个可以生成App的环境,点这里下载

    xcode,adt, 哈哈,都有

    五、标准玩法

    外卖为例,“WeX5 App与服务端交互原理” 有交互原理介绍。

    资源打进app,bass 部署到tomcat上作为服务, 这个是推荐用法。

    什么,资源咋升级?没问题,按“App资源和版本更新”将最新的资源按更新到服务器即可。

    刚下载的一个WeX5,解压后运行目录的“启动WeX5开发工具.bat”和“启动WeX5运行平台.bat”,这样就可以用浏览器连接和访问,如果App不选择打包资源,那修改的资源,App 也会自动更新。

    3.WeX5 App与服务端交互原理

    拿WeX5自带的外卖来说举例,它由三部分组成

    1. UI2/takeout 这个是页面,由页面文件.w和js以及css等构成,js中有$.ajax的请求

    2. Native/外卖这个是本地app的工程,用来打包app

    3. tomcat的webapps/baas 这个是服务端,提供步骤1中的$.ajax访问

    启动服务

    开发工具Studio中启动Tomat,这个将启动两个服务,一个是tomcat的webapps下的baas服务,另外一个是用于解析运行UI2资源的UIServer(在runtimeUIServer)。为描述方便,这里假设本机ip地址是192.168.1.1, tomcat的端口是8080

    浏览器访问

    浏览器输入

    1

    http://192.168.1.1:8080/x5/UI2/takeout/index.w

    这样就可以访问外卖功能,这个在电脑浏览器或者手机浏览器都可以(电脑推荐使用chrome浏览器)。

     解释一下这个URL8080后面的x5UIServer的名字,在tomcatserver.xml中定义,具体请参考tomat的相关说明,表示访问UIServerUI2/takeout/index.w 这个会请求到UIServer后,由UIServer做编译,生成htmljs供前端使用。

     本地App

    首先要生成App,先看看默认的App定义,在 Native/外卖 上点右键选择“编辑本地App”,向导中有三个重要的参数:

    1. 服务地址:这里应该写 http://192.168.1.1:8080, 因为baas在这个服务上

    2. 首页: 就是默认打开的页面写 /x5/UI2/takeout/index.w,这里 x5那个可以写成任意的,和前面介绍的UIServer的那个x5名字没任何关系

    3. 需要打包的资源:默认选择了takeout,这里如果选择了,那UI2/takeout下的资源会被打包到App里面,也就是说tomat中没有UISever那个服务运行也是正常的,如果不选择,则首页那个就必须写成/x5/UI2/takeout/index.w,因为默认的UIServer的名字叫x5,App启动时是通过UIServer来获取页面,和浏览器访问完全相同

     补脑

    如果takeout资源打包了,服务地址写 http://localhost 可否?

    还真不行,因为资源中有$.ajax的请求会发到 192.168.1.1:8080/baas 上,如果写localhost,那页面打开没问题,但ajax请求会遇到传说中的跨域问题,导致失败,所以这里服务地址要写baas服务的地址。换句话说,对于资源打到App的情况,服务地址更多是告诉ajax请求当前域是谁,从而避免跨域问题(所有请求都是http://192.168.1.1:8080/xxx,但app内部做了处理,会优先找打入app的资源,没有找到的资源在去请求服务端,对于app来说,是读取本地资源还是服务端请求没任何区别,从而解决跨域问题)。当然,如果没有任何ajax请求或者用插件方式发http来访问,实际上可以写 http://localhost而如果要访问多个地址,那就只能写成 http://localhost,在配合http的插件发请求(自带的plugin.http.request插件),就不能使用jquery的了(其实纯html可以用jsonp方案,不过比较麻烦,具体baidu,推荐插件方案)。

    4.Account示例程序

    UI2/demo/account

    记账本演示程序。

    演示了 list 、windowReceiver, windowDialog等的用法。

    在主页面中,windowDialog通过src属性指定页面w文件,将窗口指定为对话框。这样可打开对话框,并传递数据到对话框中。在对话框页面中,通过windowReceiver接收主页传递的数据、关闭对话框,并传递返回数据到主页。

    另外,data.save()方法,触发 data 组件的 onCustomSave 事件,事件处理函数完成具体保存操作。这里实际上通过事件触发和处理机制,实现了save保存操作的重写。允许程序员实现自定义操作。

    justep.Shell.showLeft();实现侧边栏切换显示状态。

    Swing组件,实现左右侧边栏。

    contents组件:在.w文件中使用contents组件可以实现不同页面的展现,特别是可以通过手势滑动来切换页面。contents组件使用content来展现页面,contents组件中可以包括多个content,content可以动态生成,删除,增强了页面显示的灵活性,contents组件和buttonGroup组件配合使用,使用button组件的target属性关联content,可以实现按钮和页面的绑定

    组件路径:/UI2/system/components/justep/contents

    组件标识:$UI/system/components/justep/contents/contents

    配合其它组件使用,可实现以下功能:

    滑动切换页面

    实现图片轮换效果

    模拟门户打开w页面

    新增空白content,并动态创建组件

    contents嵌套contents,分类切换页面

    通过ShellImpl的contentsXid属性指定。 可在多个页面中实现切换显示。

           this.shellImpl = new ShellImpl(this, {

                         contentsXid : "pages",

                         wingXid : "wing",

                         pageMappings : {

                                "list" : {

                                       url :"$UI/demo/account/list.w"

                                },

                                "detail" :{

                                       url :"$UI/demo/account/detail.w"

                                },

                                "classSetting": {

                                       url :"$UI/demo/account/classSetting.w"

                                }

                         }

                  });

    代码触发事件,通过事件传递数据,触发操作:

           Model.prototype.classDataAfterSave =function(event) {

                  // 通过Shell发出一个消息,通知其他页面分类数据已改变,并且在消息中携带了改变后的分类数据

                  var classData =this.comp("classData");

                  justep.Shell.fireEvent("onClassChanged", {

                         "classData" :classData.toJson()

                  });

           };

    Detail.w对应的脚本detail.js中:

    Model.prototype.onClassChanged = function(event) {

           this.comp("classData").clear();

           this.comp("classData").loadData(event.classData, truenullnulltrue);

        };

    5.Takeout示例程序

    5.1Index.w

    5.1.1模型

    Data和baasData的图标不同,baasData的图标 ,data的图标 。

    foodData(baasData)

    计算规则:

    CalcPriceText: js:'¥ ' + val('fPrice') + '元'

    calcImageURL: js:$model.transURL('./img/'+val('fImage'))

    userData(baasData)

    过滤条件userFilter:

    fID = :user

    orderData(baasData)

    过滤条件userFilter:

    fID = :user

    cartData(data)

    计算规则: calcMoney ---- js:val('fPrice') *val('fCount')

    statusData(data)

    计算规则:

    calcCartSumMoneyText ---- js:'¥ ' +$model.comp('cartData').sum('calcMoney') + '元'

    calcCartCountText----js:($model.comp('cartData').count()> 0) ? '购物车(' + $model.comp('cartData').count() +')' : '购物车'

    calcCanSaveOrder ----js:$model.comp('cartData').sum("calcMoney") > 0

    calcCanClearCart ----js:$model.comp('cartData').count() > 0

    payData(data)

    5.1.2 UI界面

    1.对话框

    Src: $UI/takeout/mapActivity.w

    2.主要内容

    四个content显示食品、购物车、订单和我的四个页面。

    四个按钮实现页面切换:foodBtn、cartBtn、orderBtn、ownBtn

    切换实现:按钮的target属性设置。

    布局组件contents上可通过右键菜单添加多个content:

    这样做估计有一个好处,那就是主要内容都在一个.w文件里,可以共用模型的定义。

    1)foodContent

    使用list组件显示食品列表foodList,在list模板中使用了 media(bootstrap) 组件。media-left中显示食品图片,类型image(html),通过bind-attr-src 将image组件的src属性和foodData的列calcImageURL绑定, val('calcImageURL')。

    media-body 中显示 “来一份”按钮 addCartBtn,三个output输出食品名称、描述和计算价格文本。

    “来一份”按钮处理代码中,下面代码

           if(cartData.find([ 'fFoodID' ], [ row.val('fID') ]).length === 0) {

           的作用是使同一食品在购物车中不能重复添加,具体份数可在购物车页面修改。也就是一种食品在购物车中只能作为一条记录出现。

           按钮的span使用bind-text属性 statusData.ref('calcCartCountText')显示购物车中的食品数量。

    2)cartContent

           两个panel,一个用于显示购物车内容;一个用于显示联系人信息。

           显示购物车内容用list组件;

           显示联系人信息用了form(html),css类是 form-horizontal。formGroup(bootstrap)

           付款类型用了radioGroup,单选按钮组。单选按钮组通过itemset属性和payData模型数据关联在一起。

          

           两个按钮:清空购物车,调用cartData.clear()方法。

    下单

    3)orderContent

           List组件显示订单内容:

    4)ownContent

    显示用户姓名、电话、地址。

    保存用户信息。

    通过定位功能获取用户位置,作为地址。

    5.2mapActivity.w

    通过 iframe 引入map.html

    在 map.html 中,通过js调用了百度地图。

    问题

    transURL

    calcImageURL: js:$model.transURL('./img/'+val('fImage'))中 transURL的用法?

           //转换动态图片URL

           Model.prototype.transURL= function(url) {

                  returnrequire.toUrl(url);

           };

    过滤条件 过滤条件userFilterfID= :user:user的用法?

    :user用法估计类似于SQL语句中的绑定变量。占个位置,便于外部传入数据。

    Model.prototype.modelLoad 函数中,直接设置:

           this.comp('userData').filters.setVar("user",this._userID);

           this.comp('orderData').filters.setVar("user",this._userID);

    media(bootstrap) 组件

    http://www.uedsc.com/bootstrap-media-object.html

    Bootstrap 中的多媒体对象(MediaObject)。这些抽象的对象样式用于创建各种类型的组件(比如:博客评论),我们可以在组件中使用图文混排,图像可以左对齐或者右对齐。媒体对象可以用更少的代码来实现媒体对象与文字的混排。

    媒体对象轻量标记、易于扩展的特性是通过向简单的标记应用 class 来实现的。你可以在 HTML 标签中添加以下两种形式来设置媒体对象:

    .media:该 class 允许将媒体对象里的多媒体(图像、视频、音频)浮动到内容区块的左边或者右边。

    .media-list:如果你需要一个列表,各项内容是无序列表的一部分,可以使用该 class。可用于评论列表与文章列表。

    formGroup(bootstrap)

    课程中提到的form-group样式和form-control有什么实质的区别呢?form-group一般用于div,form-control一般用于置于div中的标签元素。

    justep.Util.hint

    显示提示信息框:

    justep.Util.hint("请填写完整的用户信息", {

                                "type": "danger"

                         });

    当前日期格式化

    justep.Date.toString(new Date(),justep.Date.STANDART_FORMAT)

    jQuery的deferred对象

    http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html

    开发网站的过程中,我们经常遇到某些耗时很长的javascript操作。其中,既有异步的操作(比如ajax读取服务器数据),也有同步的操作(比如遍历一个大型数组),它们都不是立即能得到结果的。

    通常的做法是,为它们指定回调函数(callback)。即事先规定,一旦它们运行结束,应该调用哪些函数。但是,在回调函数方面,jQuery的功能非常弱。为了改变这一点,jQuery开发团队就设计了deferred对象。简单说,deferred对象就是jQuery的回调函数解决方案。在英语中,defer的意思是"延迟",所以deferred对象的含义就是"延迟"到未来某个点再执行。它解决了如何处理耗时操作的问题,对那些操作提供了更好的控制,以及统一的编程接口。它的主要功能,可以归结为四点。下面我们通过示例代码,一步步来学习。

    deferred对象有三种执行状态----未完成,已完成和已失败。如果执行状态是"已完成"(resolved),deferred对象立刻调用done()方法指定的回调函数;如果执行状态是"已失败",调用fail()方法指定的回调函数;如果执行状态是"未完成",则继续等待,或者调用progress()方法指定的回调函数(jQuery1.7版本添加)。前面部分的ajax操作时,deferred对象会根据返回结果,自动改变自身的执行状态;但是,在wait()函数中,这个执行状态必须由程序员手动指定。dtd.resolve()的意思是,将dtd对象的执行状态从"未完成"改为"已完成",从而触发done()方法。类似的,还存在一个deferred.reject()方法,作用是将dtd对象的执行状态从"未完成"改为"已失败",从而触发fail()方法。

    jQuery提供了deferred.promise()方法。它的作用是,在原来的deferred对象上返回另一个deferred对象,后者只开放与改变执行状态无关的方法(比如done()方法和fail()方法),屏蔽与改变执行状态有关的方法(比如resolve()方法和reject()方法),从而使得执行状态不能被改变。

    6.页面间交互视频

    6.1 页面打开和传参概述

    打开页面的三种方式:

    使用Shell,例如 UI2/portal/sample/index.w,这种方式不返回参数;

    打开对话框;

    使用内嵌页面(WindowContainer);

    传参数的三种方式:

    ?参数,进入URL,

    Params,#!参数,通过序列化也能进入URL;

    Params.data,不支持序列化,不进入URL,所以不能随链接一起分享。

    传参数的例子:

    UI2/demo/page/index.w ,这个首页中,

    点击按钮

    打开页面

    演示打开页面的方式和打开页面传参数。

    上面页面文件是 interactive/page.w

    6.2 Shell打开页面

    第一种代码:

        //"p2"是index.w中 pageMappings定义的页面标识

           justep.Shell.showPage("p2");

    第二种代码:

        var url = require.toUrl("./page2.w");

           justep.Shell.showPage(url);

    三种参数传递:

        var url = require.toUrl("./page2.w?p1=p1Value&p2=p2Value");

           var params = {

               a1: "a1Value",

               a2: 2,

               data: {

                  d1: "d1Value",

                  d2: "d2Value"

               }

           }

           justep.Shell.showPage(url,params)

    require.toUrl 相对路径转换为绝对路径。

    参数接收,都在model组件的onParamsReceive事件中。此处是在page2.w中。可在该事件处理中通过event.params访问后两种参数,也可通过this.params随时访问后两种参数。

    6.3 对话框与数据传递

    打开对话框并传递参数到对话框:有两种方法。不传参数可以使用按钮关联open操作。传参数可以向下面一样写代码。通过写代码可实现每次打开不同的页面。

    Model.prototype.button1Click = function(event){

           var dialog = this.comp("dialog");

           var url = require.toUrl("./dialog.w?p1=参数1&p2=参数2");

           dialog.open({

               src: url,

               params: {

                  a1: "简单数据a1",

                  a2: 2,

                  //data是特殊的参数, 这部分内容不能被分享

                  data: {

                      //将一个函数传递给对话框

                      fn: function(){        

                         alert("将一个函数传到对话框中");

                      }, 

                      //将data中的一行数据传给对话框

                      data1: this.comp("data1").getCurrentRow().toJson()

                  } 

               }

               

           })

        };

    对话框dialog.w中接收参数:

    Model.prototype.modelParamsReceive= function(event){

           var context = this.getContext();

           

           //获取URL中的参数

           var p1 = context.getRequestParameter("p1");

           var p2 = context.getRequestParameter("p2");

           var buf = "来自url的参数: p1=" + p1 + ", p2=" + p2 + " ";

           

           //获取简单参数

           buf += "简单参数:params.a1=" + event.params.a1 + ",params.a2=" + event.params.a2 + " ";

           

           //获取复杂参数

           buf += "复杂参数: "

           if (event.params.data){

               buf += "    params.data.fn=" + event.params.data.fn + " ";

               this.comp("dlgData").loadData([event.params.data.data1]);

               this.comp("dlgData").first();

           }

           alert(buf);

        };

    对话框关闭并返回参数给主窗口 page.w

        Model.prototype.button3Click = function(event){

           this.owner.send(this.comp("dlgData").getCurrentRow());

           this.close();

        };

    this.owner是谁?是page.w中的dialog组件。

    主窗口page.w接收对话框dialog.w返回的数据:

        Model.prototype.dialogReceive = function(event){

    alert("页面接收对话框架返回的数据:" +JSON.stringify(event.data.toJson()));

        };

    对话框的属性

    onClose指向 dialogClose函数。

    onReceive指向dialogReceive函数。

    src指向./dialog.w。

    什么时候将返回数据写入主页的data1组件的呢?用的是对话框的mapping机制。对话框mapping属性点击打开对话框

    注意对话框事件onReceive和onReceived的区别。

    onReceive在mapping之前进行,onReceived在mapping之后进行。

    6.4 内嵌页面与参数传递

    page.w页面的containerContent中有两个windowContainer组件,windowContainer1指向./page3.w,windowContainer2指向./page4.w。这样就把page3和page4作为内嵌页面放到了page中。

    windowContainer1

    src属性./page3.w?p1=p1&p2=p2同时指定了url参数。

    Params指定{a1: "a1", a2: "a2"}了第二种参数。

    Page3.js中接收了参数:

    Model.prototype.modelParamsReceive= function(event){

           var context = this.getContext();

           

           //获取URL中的参数

           var p1 = context.getRequestParameter("p1");

           var p2 = context.getRequestParameter("p2");

           var buf = "来自url的参数: p1=" + p1 + ", p2=" + p2 + "; ";

           

           //获取简单参数

           buf += "简单参数:params.a1=" + event.params.a1 + ",params.a2=" + event.params.a2 + "; ";

           

           //获取复杂参数

           buf += "复杂参数: "

           if (event.params.data){

               buf += "    params.data.d1=" + event.params.data.d1 + "; ";

               buf += "    params.data.d2=" + event.params.data.d2 + "; ";

           }

           

           var id = this.getIDByXID("container");

           $("#" + id).text(buf);

        };

    显示所有参数按钮演示了如何在页面中获取使用参数:

    Model.prototype.button1Click = function(event){

           var context = this.getContext();

           

           //获取URL中的参数

           var p1 = context.getRequestParameter("p1");

           var p2 = context.getRequestParameter("p2");

           var buf = "来自url的参数: p1=" + p1 + ", p2=" + p2 + " ";

           

           //获取简单参数

           buf += "简单参数:params.a1=" + this.params.a1 + ", params.a2=" + this.params.a2 + " ";

           

           //获取复杂参数

           buf += "复杂参数: "

           if (this.params.data){

               buf += "    params.data.d1=" + this.params.data.d1 + " ";

               buf += "    params.data.d2=" + this.params.data.d2 + " ";

           }

           alert(buf);

        };

    返回参数按钮代码:

        Model.prototype.button2Click = function(event){

           this.owner.send({r1: "r1Value"});

        };

    向主页page.w发送了名为r1的参数,值为r1Value。

    主页page.w中下面代码接收并显示了参数r1的值。

        Model.prototype.windowContainer1Receive = function(event){

           alert("接收到内嵌页面的返回数据:r1=" + event.data.r1);

        };

    主页page.w中“刷新内嵌页面”按钮执行代码:

        Model.prototype.button8Click = function(event){

           var url = require.toUrl("./page3.w?p1=p1ValueNew&p2=p2NewValueNew");

           var params = {

               a1: "a1ValueNew",

               a2: 20,

               data: {

                  d1: "d1ValueNew",

                  d2: "d2ValueNew"

               }

           }

           this.comp("windowContainer1").load(url, params);

        };

    代码重新装入内嵌页面page3,并传递了新的参数。

    Load方法智能判断,src没变只传参数;src变了刷新页面。Refresh页面会强制刷新页面。

    windowContainer2

    src属性./page4.w指定了内嵌页面。

    Params属性{data: $model.data1}将主页模型中数据组件data1的值传递给内嵌页面。

    页面./page4.w中分别使用input和list显示了参数数据:$model.params.data。

    让人比较意外的是,这种数据关联居然是双向的:即主页数据改变可实时传递到内嵌页面,内嵌页面数据改变也可实时传递到主页。原因是主页和内嵌页面UI绑定的是同一个对象,就是data1。

    主页和内嵌页面可互相访问对方的model组件

    7.页面结构及生命周期视频

    课程记录

    1.最简单的应用

    Hello

    介绍应用创建,app打包

    2.firstSPA

    自己利用页面向导创建程序。不用WeX5网站提供的视频中的方法。

    3.todoMVC

           介绍模型、窗口组件、事件、js代码等

    4.通过list显示服务端json文件中的数据

           练习list组件和data组件的用法

    goosData.json

    参考 demo/taobao /list.w

    1)  新建listJsonData应用

    2)  复制demo/taobao/cart文件夹。里面有图片和json格式的数据文件。

    3)  创建标准页面 index.w

    4)  页面model中添加data组件goodsData,根据json数据文件格式,建立数据模型列定义

    Index.js 中添加代码 (代码参考demo/taobao/list.w中同名函数)

    Model.prototype.loadDataFromFile= function(url, objData, operation) {

           if (operation) {

               objData.clear();

           }

           $.ajaxSettings.async = false;

           $.getJSON(url, function(data) {

               objData.loadData(data);

           });

        };

        // 获取商品列表

        Model.prototype.goodsDataCustomRefresh = function(event) {

           

           var url = require.toUrl("./cart/json/goodsData.json");

           this.loadDataFromFile(url, event.source, true);

        };

    5)  goodsData的onCustomRefresh事件绑定函数goodsDataCustomRefresh

    6)  index.w 的panel面板的content中添加scrollview组件。Scrollview实现下拉刷新,上划加载更多数据。

    7)  scrollview的中间content中添加list组件,设置data属性值为goodsData。list组件会自动根据关联data数据循环显示。

    8)  在li中添加row组件,row中添加output,引用data中当前行的列。

    9)  启动tomcat,运行index.w。

    10) 知识点讲解:参考教材的scrollview,list,data组件。

    表单与data组件的绑定

    5.实现单表的CRUD

           通过baas服务。

           包括通过Java实现自定义的Action

           Baas打包部署

           参考:WeX5后端服务教程.zip

    6.自己框架实现后台服务

    自己有j2ee的后台服务可以提供数据,wex5应该怎么访问呢,可以不用baas吗?

    可以使用ajax直接访问,不过返回的json数据格式要保证能加载到data组件中http://doc.wex5.com/?p=4932

     或者是像这样的:/UI2/demo/tuniu/json/cityData.json建议集成3.2.1的baas,这样数据交互会简单些可以看看baas服务视频:http://wex5.com/cn/1-wex5#06

      打包下载的那个视频(3.2.1以前版本的baas)

    7. 自己框架集成BaaS代码

    8. WebSocket通信应用

    9.播放音频视频

    10.调试

           一种需求是界面基本不变,调试后端服务。这时可在native文件夹创建app,然后,右键菜单选择编译UI资源,成功后将www文件夹内的文件复制到myeclipse调试用的tomcat服务器应用程序部署文件夹内,作为一个应用程序即可。

           在这种情况下,通过浏览器调试UI中的脚本程序是可以的。

           另外一种需求是后台服务基本不变,主要是开发调试UI。这时,应该把后端服务部署到WeX5开发环境所用的tomcat服务下。但是这个还没有尝试。

  • 相关阅读:
    leetcode每日刷题计划-简单篇day10
    leetcode每日刷题计划-简单篇day9
    leetcode每日刷题计划-简单篇day8
    leetcode每日刷题计划-简单篇day7
    leetcode每日刷题计划-简单篇day6
    leetcode每日刷题计划-简单篇day5
    leetcode每日刷题计划-简单篇day4
    leetcode每日刷题计划-简单篇day3
    设计模式解决 if-else
    线程池
  • 原文地址:https://www.cnblogs.com/mehjb/p/6127018.html
Copyright © 2020-2023  润新知