一步一步创建Sencha Architect Files(aux)


一点小牢骚:最近在做一个项目,经过寻寻觅觅发现Extjs 4.2挺符合要求的,那就它了。上了手了才发现上了贼船了,中文的开发资料巨少。上Sencha的英文官网,速度慢不说,查找一些资料也不是特别方便,谁让咱们上学的时候没有学好英文呢:(,英语老师我对不起您们啊啊啊!!。带着4,5个兄弟开发,中间发现数值控件Number Field,居然不支持千位分割符(,),太不地道了,在官网论坛上一顿查找,发现一个叫Greivin Britton的巴拿马雷锋,居然已经解决这个问题了。欢天喜地的下下来,咦,不打成包做成组件没有办法在Architect 3.0里面使用,而且多人开发,咋让兄弟们的Architect里面也用上啊,必须给整,说弄就弄了,参考各路天书资料,弄了几天都快崩溃了,老是这个不行,那个不行的,一直捅咕了3,4天才搞定,回头一看,我要骂娘了啊,啥狗屁资料啊啊啊!!!!破天荒第一次万年潜水员,准备冒个泡,给大家整个资料,帮助自己和大家梳理一下这个制作流程,希望对大家平常的开发有所帮助。

一、环境准备


(小猛所在的公司,在大连主做日本外包,所以操作系统是日文的,同志们别喷我,上有老下有小,中间还有老婆要来养,都是为了混口饭吃,大家这么高的水平估计都能看的懂,其实我也想干国内的啊,有合适的大家给介绍介绍啊!呵呵,千万不被老板看见啊!!:))
1、安装Sencha Architect 3.0
估计看这个文章的同志们都已经安了,这里就不废话了,可以到Sencha的官网上下载并安装,因为安装的时候还会从网络上下载一些相关,所以需要联网哦!

2、安装JDK,我转了JDK 7.6,这里就不罗嗦了,下载下来后,直接点击安装就OK了。

3、安装Sencha Cmd 4.0
方式1:上官网下载 Sencha Cmd4.0并安装。注意本文档作成时,Sencha Cmd 5.0已经发布,Cmd 5.0,我没有用过,以下所有操作都是在Cmd 4.0上进行的。
方式2:稍有复杂,在成功安装Sencha Architect 3.0的基础上,打开Architect的安装目录,如下图。

点击打开assets\cmd\4.0.4.84文件夹,重大发现呢!!有我们要的Cmd的压缩包!!其实Architect内部调用Cmd命令,就是通过这个压缩包实现的,如下图。

随便找个地方给解开,我找了D盘来放,如下图。

在环境变量里设置Path路径(你可千万别说你不知道在哪里设置这个环境变量!),如下图

上述两个方法,任选其一安装完毕后。

打开命令窗口,输入sencha,显示如下图。

OK,成功安装上了,呵呵,大家可以耍了呢。

二、使用Cmd生成Package


1、生成Workspace,必须生成Workspace,才能继续执行后续的命令。
在窗口中输入:sencha generate workspace d:/workspace

在D盘下生成Workspace所对应的文件夹,下面会有.sencha和packages两个文件夹。

2、生成Package
接下来的操作,为方便起见,将以我自己这次做成Package组件为例进行讲解。
在命令窗口中输入cd D:\workspace命令,进入D:\workspace文件夹。
在命令窗口中输入sencha generate package NumericField,必须进入workspace文件夹,才能输入生成Package的命令,如下图。

NumericField,就是咱们要生成的Package的名字。

三、编辑生成的Package


1、简单介绍一下生成的文件夹和相关文件
进入生成的D:\workspace\packages\NumericField,显示如下的文件结构,如下图。

  • .sencha 文件夹:Cmd生成的与Package相关的基础配置文件夹,不用修改。
  • docs 文件夹:可以存入与当前Package相关的介绍文档,不放也OK,本次未触及。
  • example 文件夹:可以放入如何使用该Package的例子程序,不放也OK, 本次未触及。
  • licenses 文件夹:该Package的License方面的文件,不做处理也OK, 本次未触及。
  • overrides 文件夹:根据需要自行设置,本项目中未触及。
  • resources 文件夹:如果当前Package需要使用到css或是图片等一些资源,可以在将相关内容存入该文件夹中。
  • sass 文件夹:如果当前Package使用到sass一些定义,可以将相关文件存入该文件夹中,本次未触及
  • src 文件夹:代码文件存放地,必须要放的!!!
  • build.xml 文件:build处理流程文件,基本上不需要修改,本次未触及。
  • package.json 文件:package的定义文件,非常非常重要,修改是必须的哦!!!
  • Readme.md 文件:不多说了,你懂得,就是Readme文件

2、将代码装入Src文件夹中
Src文件夹中放的是,最重要的文件之一源代码。本次放入NumericField.js。对应的类继承自Ext.form.field.Number,是对Number做了千位分割符和货币符号的扩展。具体代码见附录。

3、生成architect文件夹,并装入NumericField.Definition.js
在用Package命令生成的文件夹中,没有architect文件夹,如果没有该文件夹,无法被Architect 3.0加载,所有必须手动创建这个文件夹,如下图。

文件夹生成后,在该文件夹中手动创建NumericField.Definition.js,该文件会定义这个组件在Architect 3.0中的基本信息。

以上述内容为例简单介绍一下。

  • ClassAlias:控件别名。
  • ClassName:类名。
  • Inherits:从那个类继承而来。
  • AutoName:控件创建时,自动带上控件名称。
  • HelpText:控件的帮助信息。

Toolbox(参考下图)

  • Name:在ToolBar中显示该控件的名称。
  • Category:在Architect中导入后的目录名称。
  • Groups:在默认组中显示在哪个Group中。

后续还可以配置Config,定义控件被加载时控件的默认属性,这里就不写了,大家自己查查吧,让你们体会一下我的痛苦!!

4、修改package.json文件,如下图。

内容有点多,整点重点的说说。
Architect中
CompatFrameworks:支持的ext版本。
Classes中
Definition:定义js文件名,就是咱们上面定义的NumericField.Definition.js。
ClassName:类名
Js:定义的代码文件。就是咱们上面定义的NumerField.js
Css:使用到的css,因本控件中无使用所以就不用填写。

5、接下来最最重要的一步,将做好的控件包文件名重新处理一下(就是这一步困住我好几天啊,就是因为不太清楚需要这样处理,造成一直无法加载),如下图

将package中NumericField文件夹中,追加一个叫1.0的文件夹,代表该版本为1.0,
将前面步骤作好的Package包中的所有内容,移入到这个1.0文件夹中,如下图

好,至此我们香喷喷的Package就算做好了,但是它还不是Sencha Architect Files,其他同志们还是不能非常方便的导入它,咋办?!且听下章分解。

四、Architect中生成Sencha Architect Files


1、打开 Architect3.0,点击Edit-Preferences-File,出现如下图

将Extensions改成:D:/workspace/packages,其实把这里的东西拷贝到它默认的Extensions路径中也可以,随便大家了,点save保存。

2、在Toolbar的Extensions中就能看见这个控件了。如果不行,请重启Architect

右键点击该控件,如果有在Package下还有2.0,3.0的文件夹,这时候可以进行选择。

3、导出Sencha Architect Files(aux文件)
右键点击控件,选中Package Extensions,弹出如下窗口。

选好保存路径和Archive Name文件名,点击保存,就会生成一个Numberic Field.aux文件。
至此导出大成功!!!!掌声!!!!
接下来,把这个文件发给同志们,然后各个同志们在Architect中点击Install User Extension,就可以把这个控件安装到自己的Architect中。
啥?找不到在什么地方,能不能再来个图?!大胆,把这个小子拖出去!!!!

附录:
NumericField.js原代码:没有办法在代码在word里面排版就是这个德行了。大家忍着点吧。


/*
 * GNU General Public License Usage
 * This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file.  Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
 *
 * http://www.gnu.org/licenses/lgpl.html
 *
 * @description: This class provide aditional format to numbers by extending Ext.form.field.Number
 *
 * @author: Greivin Britton
 * @email: 
 * @version: 2 compatible with ExtJS 4
 */
Ext.define('Ext.ux.form.NumericField', 
{
    extend: 'Ext.form.field.Number',//Extending the NumberField
    alias: 'widget.numericfield',//Defining the xtype,
    currencySymbol: null,
    useThousandSeparator: true,
    thousandSeparator: ',',
    alwaysDisplayDecimals: false,
    fieldStyle: 'text-align: right;',
	initComponent: function(){
        if (this.useThousandSeparator && this.decimalSeparator == ',' && this.thousandSeparator == ',') 
            this.thousandSeparator = '.';
        else 
            if (this.allowDecimals && this.thousandSeparator == '.' && this.decimalSeparator == '.') 
                this.decimalSeparator = ',';
        
        this.callParent(arguments);
    },
    setValue: function(value){
        Ext.ux.form.NumericField.superclass.setValue.call(this, value != null ? value.toString().replace('.', this.decimalSeparator) : value);
        
        this.setRawValue(this.getFormattedValue(this.getValue()));
    },
    getFormattedValue: function(value){
        if (Ext.isEmpty(value) || !this.hasFormat()) 
            return value;
        else 
        {
            var neg = null;
            
            value = (neg = value < 0) ? value * -1 : value;
            value = this.allowDecimals && this.alwaysDisplayDecimals ? value.toFixed(this.decimalPrecision) : value;
            
            if (this.useThousandSeparator) 
            {
                if (this.useThousandSeparator && Ext.isEmpty(this.thousandSeparator)) 
                    throw ('NumberFormatException: invalid thousandSeparator, property must has a valid character.');
                
                if (this.thousandSeparator == this.decimalSeparator) 
                    throw ('NumberFormatException: invalid thousandSeparator, thousand separator must be different from decimalSeparator.');
                
                value = value.toString();
                
                var ps = value.split('.');
                ps[1] = ps[1] ? ps[1] : null;
                
                var whole = ps[0];
                
                var r = /(\d+)(\d{3})/;
                
                var ts = this.thousandSeparator;
                
                while (r.test(whole)) 
                    whole = whole.replace(r, '$1' + ts + '$2');
                
                value = whole + (ps[1] ? this.decimalSeparator + ps[1] : '');
            }
            
            return Ext.String.format('{0}{1}{2}', (neg ? '-' : ''), (Ext.isEmpty(this.currencySymbol) ? '' : this.currencySymbol + ' '), value);
        }
    },
    /**
     * overrides parseValue to remove the format applied by this class
     */
    parseValue: function(value){
        //Replace the currency symbol and thousand separator
        return Ext.ux.form.NumericField.superclass.parseValue.call(this, this.removeFormat(value));
    },
    /**
     * Remove only the format added by this class to let the superclass validate with it's rules.
     * @param {Object} value
     */
    removeFormat: function(value){
        if (Ext.isEmpty(value) || !this.hasFormat()) 
            return value;
        else 
        {
            value = value.toString().replace(this.currencySymbol + ' ', '');
            
            value = this.useThousandSeparator ? value.replace(new RegExp('[' + this.thousandSeparator + ']', 'g'), '') : value;
            
            return value;
        }
    },
    /**
     * Remove the format before validating the the value.
     * @param {Number} value
     */
    getErrors: function(value){
        return Ext.ux.form.NumericField.superclass.getErrors.call(this, this.removeFormat(value));
    },
    hasFormat: function(){
        return this.decimalSeparator != '.' || (this.useThousandSeparator == true && this.getRawValue() != null) || !Ext.isEmpty(this.currencySymbol) || this.alwaysDisplayDecimals;
    },
    /**
     * Display the numeric value with the fixed decimal precision and without the format using the setRawValue, don't need to do a setValue because we don't want a double
     * formatting and process of the value because beforeBlur perform a getRawValue and then a setValue.
     */
    onFocus: function(){
        this.setRawValue(this.removeFormat(this.getRawValue()));
        
        this.callParent(arguments);
    }
});

作者:猛士天下行(简称:小猛