起步软件技术论坛
搜索
 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 3413|回复: 7

[分享] 关于Wex5自定义组件的创建细节描述

  [复制链接]

7

主题

41

帖子

199

积分

初级会员

Rank: 2

积分
199
QQ
发表于 2016-11-30 14:29:41 | 显示全部楼层 |阅读模式
   之前一段时间研究了一下关于自定义组件的相关资料,只可惜, 小弟才疏学浅,老是不得要领,就此只好日夜苦思,终于,凭借努力初步的完成了自己的自定义组件,接下来与大家分享一下小弟的开发步骤。

评分

参与人数 2威望 +60 收起 理由
少翊 + 10 很给力!
半导体 + 50 赞一个!

查看全部评分

89

主题

627

帖子

4216

积分

论坛元老

Rank: 8Rank: 8

积分
4216
QQ
发表于 2016-12-2 09:16:01 | 显示全部楼层
楼主 上干货啊
时也运也命也,非吾之所能也。
回复 支持 反对

使用道具 举报

7

主题

41

帖子

199

积分

初级会员

Rank: 2

积分
199
QQ
 楼主| 发表于 2016-12-2 09:58:56 | 显示全部楼层

噗。。  刚刚经理找我商量一个项目的细节。。 一回头我给忘记了。。  下午有时间我整理一下
回复 支持 反对

使用道具 举报

7

主题

41

帖子

199

积分

初级会员

Rank: 2

积分
199
QQ
 楼主| 发表于 2016-12-2 10:19:26 | 显示全部楼层
根据官方的API描述  先讲解一下wex5自定义组件开发包含的几种时态问题

1.设计时态
简而言之就是你在使用wex5开发程序的时候见到的视图里呈现的组件形态,此时的组件并没有放在html里面的功能,它存在的意义只是让空间可视化,还有可编辑性。
QQ图片20161202101415.png
2.运行时态
和设计不一样,这个时候的组件已经是在Html中了,他具备了执行力,可以完成它所具备的功能。 QQ图片20161202101523.png



先要明白这个才能知道接下来我说的

接下来看看wex5的组件在system中的文件分布吧。
U{XXRWMN~FY~DPJQN{BSXIN.png


很明显可以看到  wex5中的组件有很标准的文件夹命名。
designer文件夹里面存放的就是 设计时态的组件。
下面的那些js文件都是运行时态的组件
运行时态先不说,我们一起看看设计时态。

回复 支持 反对

使用道具 举报

7

主题

41

帖子

199

积分

初级会员

Rank: 2

积分
199
QQ
 楼主| 发表于 2016-12-2 11:04:47 | 显示全部楼层
QQ图片20161202102316.png 现在刚刚我们说的组件存放路径下  System/components/justep/ 新建一个mybtn的文件夹,里面的细节如图。
我们一个一个来处理这

这里必须要提到一个官方的一段介绍了
http://doc.wex5.com/custom-comp-02/

在mybtn.xml 中的代码设计  为了省时间  我就直接复制上面这个说明里面的

<!-- 创建根元素,可以同时定义多个element -->
<elements>
    <!-- 定义组件配置,这里的名称通常定义为运行时组件的名称
             tag-name 节点的标签名名称
             icon  组件显示在工具箱上面的图标, 默认存放在designer/img下
         text 组件文本描述信息
             binding-component 跟运行时组件绑定
             component-type 组件类型,可自定义, 详细可参见设计时组件开发文档 -->
    <element name="$UI/system/components/justep/button/button"
        tag-name="a" icon="button.gif" binding-component="$UI/system/components/justep/button/button"
        component-type="formControl" design-view="web-designer">
        <!-- 定义要可视化编辑的属性 -->
        <properties>
            <!-- 定义xid属性,所有组件都有这个属性 -->
            <property name="xid" text="编号" required="true" />

            <!-- 定义class样式属性,默认情况下会继承公共配置中的定义的 class公共属性,
            继承后公共属性上定义的配置直接体现到当前属性上,比如这里没有editor-ref,
            但会继承了公共属性中的editor-ref,该属性就自动默认带有class属性编辑器 -->
            <property name="class" text="class" editor-ref="classSelector">
                <editor-parameter><![CDATA[                {
                "0base": {
                    label: "基础样式",
                    value: "btn"
                },   
                "1color":{
                    label: "颜色样式",
                    value: "btn-default|btn-primary|btn-success "
                },
                "2size": {
                    label: "尺寸样式",
                    value: "btn-lg|btn-sm|btn-xs",
                    require: false
                },
                "3icon": {
                    label: "图标位置",
                    value: "btn-icon-left|btn-icon-top|btn-icon-right|btn-icon-bottom",
                    require: false
                }
            }
            ]]></editor-parameter>
            </property>
            ......

            <!-- 包含数据绑定属性 ,$UI/system/components/designerCommon/commonConfig.xml
            为为目标文件路径#号后面的//common-properties/group[@name='bind']为标准的xpath表达式 -->
            <include
                path="$UI/system/components/designerCommon/commonConfig.xml#//common-properties/group[@name='bind']" />
        </properties>


        <!-- 定义当前组件的事件 -->
        <events>
            <event name="onClick" type="event" text="点击事件" />

            <!-- 包含公共事件 -->
            <include
                path="$UI/system/components/designerCommon/commonConfig.xml#//html-evens/*" />
        </events>

        <!-- 定义模板 -->
        <templates>
            <!-- 默认模板,创建当前组件时会生成模板中的节点代码 -->
            <template name="default"><![CDATA[
            <a component="$UI/system/components/justep/button/button" class="btn btn-default"
                 label="button">
                <i/><span></span>
            </a>         ]]></template>
        </templates>
    </element>
</elements>



这是很简单的控件xml文件。。 具体的可以参考上面的链接。。。  细节。。。细节太多了 我能不说么。。当然开玩笑的。。  




回复 支持 反对

使用道具 举报

7

主题

41

帖子

199

积分

初级会员

Rank: 2

积分
199
QQ
 楼主| 发表于 2016-12-2 11:07:11 | 显示全部楼层
这段代码中的
有一个properties节点,里面有一个property节点,里面的内容就是组件显示在左下角属性框中的属性。
<property name="xid" text="编号" required="true" />这就是xid的属性。
如果你需要class的属性
<property name="name" text="名称" required="true" />

property节点也会有一个属性editor-ref,是不是发现wex5组件的class右边都会有一个按钮可以选择class的弹框? 这个属性就是这个作用的,
但是,除了一些wex5内置的属性编辑器,大部分编辑器还是需要我们声明以下的。

例如这里是action的选择框
<property name="actionUrl" text="绑定action路径" required="true" editor-ref="serviceSelector" editor-parameter="{type:'service'}"/>
里面绑定了一个serviceSelector的editor-ref属性但是,这个属性并不是想class那样是内置的。我们需要手动声明一下
于是下面有一个节点
<property-editors>
  <property-editor name="serviceSelector" type="dialog"
      url="$UI/system/components/justep/data/designer/setService.w"
      editor-parameter="{width:800,height:600}" >
  </property-editor>
</property-editors>               

这样他才会有右边的小btn的功能。应该很容易看懂吧。。不说了。。大概意思就是制定弹出的页面和大小
至于刚刚说的class怎么回事,大哥  麻烦认真看一下上面的结构  class那面那么大一段不要无视。。

<events>
            <event name="onClick" type="event" text="点击事件" />

            <!-- 包含公共事件 -->
            <include
                path="$UI/system/components/designerCommon/commonConfig.xml#//html-evens/*" />
        </events>

这一段也很好理解。。 就是给控件的事件页面添加可配置的东东。
不明白的你可以看看button的事件框去看看。
include标签是默认的事件 一般都请带上。


<!-- 定义模板 -->
        <templates>
            <!-- 默认模板,创建当前组件时会生成模板中的节点代码 -->
            <template name="default"><![CDATA[
            <a component="$UI/system/components/justep/button/button" class="btn btn-default"
                 label="button">
                <i/><span></span>
            </a>         ]]></template>
        </templates>
这个就是你拉出了组件之后出现在源码中的一段代码。。
回复 支持 反对

使用道具 举报

7

主题

41

帖子

199

积分

初级会员

Rank: 2

积分
199
QQ
 楼主| 发表于 2016-12-2 11:22:28 | 显示全部楼层
define(function(require) {
        var $ = require("jquery");
        var Util = require("$UI/system/components/justep/common/designer/common");
        var xuiService = require("$UI/system/components/designerCommon/js/xuiService");
        var xuiDoc = xuiService.getXuiDoc();
        var Button = require("../Myb");

        require('css!./css/button').load();

        var _Button = Button.extend({
                init : function(value, bindingContext) {
                        var $domNode = $(this.domNode);
                        this.callParent(value, bindingContext);
                        var cfg = Util.attr2js($domNode, [ 'label', 'icon', 'image' ]);
                        if (cfg)
                                this.set(cfg);
                        var onclick = xuiDoc.get(this,'onClick');
                        if (onclick && 0 < onclick.indexOf('operation')) {
                                // 操作感知
                                this.on('onClick', onclick);
                        }
                        $domNode.removeAttr('onclick').off('click');
                        this._d_inited_ = true;
                        this._getLabelNode().attr('d_selectable', false).attr("d_canRemove", false).attr("d_canAddChild", false);
                        this._getIconNode().attr('d_selectable', false).attr("d_canRemove", false).attr("d_canAddChild", false);
                        this._getImgNode().attr('d_selectable', false).attr("d_canRemove", false).attr("d_canAddChild", false);
                },
                bindOperation : function(data) {
                        if (data && data.eventName)
                                this.on(data.eventName, data.value);
                },
                _getImgUrl : function(icon) {// "icon-refresh"/"img:xxx.png|xxx.png"
                        if (typeof (icon) === 'string' && 0 === icon.indexOf('img:')) {
                                var ipos = icon.indexOf('|');
                                if(!this.disabled || ipos < 0){
                                        if (ipos < 0)
                                                ipos = icon.length;
                                        return icon.slice(4, ipos);
                                }else        return icon.slice(ipos);
                        }
                },
                propertyChangedHandler : function(key, oldVal, value) {
                        var $img,$icon,url,newImg;
                        switch (key) {
                        case "label":
                                this.callParent(key, oldVal, value);
                                if (this._d_inited_)
                                        xuiDoc.updateText(this._getLabelNode());
                                break;
                        case "disabled":
                                if (this.$domNode) {
                                        if (this.isImgIcon) {
                                                $img = this._getImgNode();
                                                $icon = this._getIconNode();
                                                $icon.removeAttr('class');
                                                xuiDoc.updateProperties($icon, [ 'class' ]);
                                                newImg = false;
                                                if ($img.size() <= 0){
                                                        newImg = true;
                                                        this._getLabelNode().before('<img d_selectable="false" d_canRemove="false"/>');
                                                }
                                                $img = this._getImgNode();
                                                //这个逻辑是为了同步设计时模型,同步后在刷新设计器显示,特殊处理
                                                url = this._getImgUrl(value);
                                                $img.attr('src', url?url:'');
                                                if(newImg) xuiDoc.updateNodes($img);
                                                else xuiDoc.updateProperties($img, ['src']);
                                                //这是为了在设计器正常显示
                                                $img.attr('src', this.imgIcon[this.disabled ? 1 : 0]);
                                        }
                                }
                                break;
                        case "icon":
                                if (oldVal != value) {
                                        this._setIcon(this.icon || this.opIcon);
                                        if (this.$domNode) {
                                                if (!this.isImgIcon) {
                                                        $icon = this._getIconNode();
                                                        if (oldVal)
                                                                $icon.removeClass(oldVal);
                                                        if (this.opIcon)
                                                                $icon.removeClass(this.opIcon);
                                                        if (value)
                                                                $icon.addClass(this.icon || this.opIcon);
                                                        xuiDoc.updateProperties($icon, [ 'class' ]);
                                                        $img = this._getImgNode();
                                                        if ($img.size() > 0) {
                                                                xuiDoc.deleteComponent([ $img.attr('d_id') ]);
                                                                $img.remove();
                                                        }
                                                } else {
                                                        $img = this._getImgNode();
                                                        if (value) {
                                                                $icon = this._getIconNode();
                                                                $icon.removeAttr('class');
                                                                xuiDoc.updateProperties($icon, [ 'class' ]);
                                                                newImg = false;
                                                                if ($img.size() <= 0){
                                                                        newImg = true;
                                                                        this._getLabelNode().before('<img d_selectable="false" d_canRemove="false"/>');
                                                                }
                                                                $img = this._getImgNode();
                                                                //这个逻辑是为了同步设计时模型,同步后在刷新设计器显示,特殊处理
                                                                url = this._getImgUrl(value);
                                                                $img.attr('src', url?url:'');
                                                                if(newImg) xuiDoc.updateNodes($img);
                                                                else xuiDoc.updateProperties($img, ['src']);
                                                                //这是为了在设计器正常显示
                                                                $img.attr('src', this.imgIcon[this.disabled ? 1 : 0]);
                                                        }
                                                }
                                        }
                                }
                                break;
                        default:
                                this.callParent(key, oldVal, value);
                        }
                }
        });



        return {
                '$UI/system/components/justep/Myb/Myb' : _Button,
       
        };
});


以上是mybtn.js里面的代码   
init属性是新建时触发
propertyChangedHandler  这个就是控件的属性被修改的时候,比如说,你把空间的xid修改了,就会触发这个事件

最后的返回值一定要注意按这个标准写。

回复 支持 反对

使用道具 举报

7

主题

41

帖子

199

积分

初级会员

Rank: 2

积分
199
QQ
 楼主| 发表于 2016-12-2 11:22:58 | 显示全部楼层
其实本来就没撒可以讲的。。 难就难在运行时和注册。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|X3技术论坛|Justep Inc.    

GMT+8, 2025-6-23 04:19 , Processed in 0.107202 second(s), 30 queries .

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表