React 可视化开发工具 Shadow Widget 非正经入门(之二:分离界
本系列博文从 Shadow Widget 作者的视角,解释该框架的设计要点。本篇讲解转义标签、json-x、投影定义,这几项与 "如何分离界面设计" 有关。 1. 找一个 JSX 替代品如上一篇 "非正经入门(之一)" 所述,Shadow Widget 要克服 "JSX浆糊" 的不利影响,要找一个 JSX 替代品。 比如下面 JSX 表达方式: return <h1 id={user.id}>Dear {user.name},{welcomeMsg(user)}</h1>; 等效于: return React.createElement( H1,{id:user.id},"Dear ",user.name,",welcomeMsg(user) ); 创建一个 Element,需传递三项信息: [ [ReactClass,props],child1,child2... ] 其中, 2. 转义标签为了方便在 html 网页文件中描述用户界面,我们定义 "转义标签" 的表达方式,如下: <div $=Panel> <div $=P> <span $=Span>Referece:</span> <span $=A src='http://example.com'>example.com</span> </div> </div> 转义标签无非将所有 HTML 标签划分为行内标签与 block 标签,前者用 在转义标签中定义的属性,比如上面的 转义标签具有良好可读性,所以,它在 3. 第一眼是妖孽,多半就是妖孽React 支持服务侧渲染,这个特性似乎鼓励了其生态链上若干工具额外拓展服务侧功能。比如 react-router 中 Router 组件的 history 属性,既可以是 这个 某种程度上 React 的服务侧渲染也多少沾点 "妖气",有些人仅为了解决 SEO 优化用它,仔细想想有点本末倒置了。它的初始需求源于 google 之类的搜索引擎不认 JSX,因为 JSX 服务于编程,编程脚本原不该由搜索引擎关注的,该关注的只是一些静态文本。处理静态文本没必要拉上 React 一家子吧?但事实却是,我们非得套用一个客户侧编程风格,用 JS 开发的服务侧渲染工具,你说妖不妖? 4. 分离界面设计在分离界面之前,我们还需建立路径索引机制。 Shadow Widget 通过一颗树(Widget 树,R 树)管理由它定义的界面,各节点都有 key 值作标识,既可以显示指定一个 key 值,也可以缺省,缺省时由系统自动生成一个数字来表示。这果颗树的根节点是 有了路径索引机制,我们能将界面描述与它的行为定义分离开了。比如这么定义界面: <div $=BodyPanel key='body'> <div $=Panel key='toolbar'> <div $=P key='p'> <span $=Button key='btn1'>Test</span> </div> </div> </div> 这么定义 main['.body.toolbar.p.btn1'] = { $onClick: function(event) { alert('clicked'); },}; 界面的转义标签在 5. 表达复杂的 props 数据json-x 数据与转义标签都与 JSX 对等,但传递 除了函数,描述复杂的 props 数据时,json-x 的表达能力是完整的,因为它本来就是 javascript 数据,但转义标签受 html 标签格式的影响,要改用 JSON 字串来表示,比如: <div $=Panel title='tool bar' width='{400}'> </div> 属性值用 6. idSetter 函数实施界面与底层分离除了投影定义,还有一种指定 idSetter 函数的方式,若简单去理解,该方式是投影定义的一个变种,同样实现特定界面元素的行为定义的动态绑捆。 举例来说,界面这么描述: <div $=BodyPanel key='body'> <div $=Panel key='toolbar'> <div $=P> <span $=Button $id__='btn1'>Test</span> </div> </div> </div> Javascript 这么定义: idSetter['btn1'] = function(value,oldValue) { if (value <= 2) { if (value == 1) { // init process this.setEvent( { $onClick: function(event) { alert('clicked'); },}); // ... } else if (value == 2) { // did mount // ... } else if (value == 0) { // will unmount // ... } return; } // render process ... }; 这种书写方式与上面投影定义的方式是等效的,投影类中该在 使用 idSetter 函数的优点是,相应界面节点的绝对路径不必完整定义,即路径上各段不必显式给出 key 值,系统由 7. 建立 W 树供随时节点定位Flux 框架要求节点间数据流向要遵守严格的约束,React 不惜牺牲编程便利性,刻意隐藏了内建的那颗虚拟 DOM 树,导致编程中跨节点调用非常不便,各节点都被一层黑墙包裹,无法探知周围都有哪些节点存在,好在 React 为这个黑墙开了一扇单向玻璃窗: 既然 Shadow Widget 引入 MVVM 框架,在 Component 的 API 层面限制节点间互通已不合时宜,单向数据流应该在更高层面的设计去保证。所以,Shadow Widget 引入了 "W 树" 的概念,也就是,所有符合规格的 Component 节点(即源于 WTC 类创建的节点)都串接在一颗树上。树中各节点都有唯一 "路径" 标示,节点之间还可以用 "相对路径" 或 "绝对路径" 引用,比如: this.componentOf('//') // get parent component this.componentOf('//brother') // brother node this.componentOf('sub.child') // child node this.componentOf('./seg.child') // by relative path this.componentOf('.body.top.toolbar') // by absolute path 有了 W 树设计,router 规划将变得简单明了,比方下图界面,把两个可切换的页
(本文完) 本专栏历史文章:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- c – 为引用分配引用是否为有效操作?
- 设置RubyMine2以运行和调试Sinatra应用程序
- HDU--2206 -- IP的计算 [正则表达式]
- ruby – RVM安装:`/usr/local/rvm’:权限被拒绝
- flex4.5 + .net4.0 通过FluorineFx的AMF3协议 以
- 如果出现C#.NET错误,如何使代码跳过某些内容
- 免ajax省市三级联动:http://runjs.cn/detail/rc
- Aspect 切点表达式(xml形式,非注解形式的)
- ruby-on-rails – 启用了rails的Rubocop和Style
- postgresql – 无法从dump导入到heroku postgres