zoukankan      html  css  js  c++  java
  • Extjs4中的常用组件:Grid、Tree和Form

    至此我们已经学习了Data包和布局等API。下面我们来学习作为Extjs框架中我们用得最多的用来展现数据的Grid、Tree和Form吧!
    目录:
     
    5.1. Grid panel                                          
         Grid应该是我们在开发时使用的最多的组件之一。Extjs4对其进行了重大的改进。
         Extjs4与Extjs3的Grid生成不同的HTML。Sencha称其为智能渲染(Intelligent Rendering)。Extjs3中即使不需要Grid的所有特性,它也会生成整套HTML。而Extjs4就只会渲染Grid所用到的特性,这样就使渲染最小化且提高了性能。
         在学习Extjs4中Grid的新特性前,让我们先了解在Extjs4中如何创建一个简单的Grid吧!
    Ext.create("Ext.grid.Panel", {
         store: Ext.create("Ext.data.ArrayStore", {
              fields: [{name: "book", name: "author"}],
              data: [["Ext  JS 4: First Look", "Loiane Groner"]]
         }),
         columns: [{
              text: "Book",
              flex: 1,
              sortable: false,
              dataIndex: "book"
         },{
              text: "Author",
              100,
              sortable: true,
              dataIndex: "author"
         }],
         height: 80,
         widht: 300,
         title: "Simple Grid",
         renderTo: Ext.getBody()
    });
    通过上述的代码片段,我们可以知道Extjs4和Extjs3在创建简单Grid时是无差别的。
     
    5.1.1. Columns                                            
         Extjs4中将Grid的column类归纳到一个独立的Ext.grid.column包中。
         现在我们一起学习各类型的column吧。
         首先定义Model类和Store并加载示例数据:
         Ext.define('Book', {

    extend: 'Ext.data.Model',

    fields: [

    {name: 'book'},

    {name: 'topic', type: 'string'},

    {name: 'version', type: 'string'},

    {name: 'released', type: 'boolean'},

    {name: 'releasedDate', type: 'date'},

    {name: 'value', type: 'number'}

    ]

    });

    var store = Ext.create('Ext.data.ArrayStore', {

    model: 'Book',

    data: [

    ['Ext JS 4: First Look','Ext JS','4',false,null,0],

    ['Learning Ext JS 3.2','Ext JS','3.2',tr ue,'2010/10/01',40.49],

    ['Ext JS 3.0 Cookbook','Ext JS','3',true,'2009/10/01',44.99],

    ['Learning Ext JS','Ext JS','2.x',true,'2008/11/01',35.99],

    ]

    });  
     
    然后就是创建Grid了:
    Ext.create('Ext.grid.Panel', {
    store: store,
    550,
    title: 'Ext JS Books',
    renderTo: 'grid-example',
    selModel: Ext.create('Ext.selection.CheckboxModel'), //1
    columns: [
    Ext.create('Ext.grid.RowNumberer'), //2
    {
    text: 'Book',//3
    flex: 1,
    dataIndex: 'book'
    },{

    text: 'Category', //4

    xtype:'templatecolumn',

    100,

    tpl: '{topic} {version}'

    },{

    text: 'Already Released?', //5

    xtype: 'booleancolumn',

    100,

    dataIndex: 'released',

    trueText: 'Yes',

    falseText: 'No'

    },{

    text: 'Released Date', //6

    xtype:'datecolumn',

    100,

    dataIndex: 'releasedDate',

    format:'m-Y'

    },{

    text: 'Price', //7

    xtype:'numbercolumn',

    80,

    dataIndex: 'value',

    renderer: Ext.util.Format.usMoney

    },{

    xtype:'actioncolumn', //8

    50,

    items: [{

    icon: 'images/edit.png',

    tooltip: 'Edit',

    handler: function(grid, rowIndex, colIndex) {

    var rec = grid.getStore().getAt(rowIndex);

    Ext.MessageBox.alert('Edit',rec.get('book'));

    }

    },{

    icon: 'images/delete.gif',

    tooltip: 'Delete',

    handler: function(grid, rowIndex, colIndex) {

    var rec = grid.getStore().getAt(rowIndex);

    Ext.MessageBox.alert('Delete',rec.get('book'));

    }

    }]

    }]

     
    });
    效果如下:
    1. 通过selModel配置项设置选择模式,具体有三种选择模式:RowModel、CellModel和CheckboxModel,其中CheckboxModel会自动插入Checkbox列作为Grid的第一列;
    2. 在配置columns时我们创建了一个序号列(Ext.create("Ext.panel.RowNumberer"));
    3. Book列没有指定列类型,那么默认以string数据类型来展现数据;
    4. Category列指定列类型为templatecolumn,就是说可以通过tpl属性来设置该列数据呈现的样式。tpl属性为string数据类型,可通过{Model实例中name}的形式来访问记录中任意的字段值;
    5. Already Released?列指定列类型为booleancolumn,就是说该列对应的Model实例属性值为boolean类型,而且我们可以通过trueText和falseText来设置值为真/假时分别呈现什么内容;
    6. Released Date列指定列类型为datecolumn,并通过format属性来设置以某种格式来呈现日期信息;
    7. Price列指定列类型为numbercolumn,而这里通过设置renderer:Ext.util.Format.usMoney来设置该列的呈现样式。renderer属性是从Column类(所有Column类型的父类)继承得到的,所以各个column类均可设置该属性,属性值为function(value){........; return "呈现的内容";},参数value为该单元格中对应的Model实例的属性值。而Ext.util.Format.usMoney是内置的格式化函数,当然我们可以自定义Ext.util.Format.rmbMoney的函数啦;
    8. 最后一列没有表头并指定列类型为actioncolumn,该列用于添加行级的增、删、查、改等操作按钮。
     
     
    5.1.2. Feature                                        
         如果我们想在Extjs3中为grid添加新功能,我们一般要创建或扩展GridPanel类。但官方没有提供一种统一的方式去处理这个问题。在Extjs4中我们可以通过继承Ext.grid.feature.Feature(类中含有公用方法和属性)来实现上述的需求。(译者语:具体如何定义Ext.grid.feature.Feature子类,我还没试过)
         在Ext.grid.feature包中有7个类:AbstractSummary,Chunking,Feature,Grouping,GroupingSummary,RowBody和Summary。
         下面我们来学习如何使用feature,具体如下
         features:[{
              groupHeaderTpl: "Publisher: {name}",
              ftype: "groupingsummary"
         }]
     
    5.1.2.1. Ext.grid.feature.Grouping                                  
         直接上代码吧!

    Ext.define('Book', {

    extend: 'Ext.data.Model',

    fields: ['name', 'topic']

    });

    var Books = Ext.create('Ext.data.Store', {

    model: 'Book',

    groupField: 'topic',

    data: [{

    name: 'Learning Ext JS',

    topic: 'Ext JS'

    },{

    name: 'Learning Ext JS 3.2',

    topic: 'Ext JS'

    },{

    name: 'Ext JS 3.0 Cookbook',

    topic: 'Ext JS'

    },{

     
    name: 'Expert PHP 5 Tools',

    topic: 'PHP'

    },{

    name: 'NetBeans IDE 7 Cookbook',

    topic: 'Java'

    },{

    name: 'iReport 3.7',

    topic: 'Java'

    },{

    name: 'Python Multimedia',

    topic: 'Python'

    },{

    name: 'NHibernate 3.0 Cookbook',

    topic: '.NET'

    },{

    name: 'ASP.NET MVC 2 Cookbook',

    topic: '.NET'

    }]

    });

    Ext.create('Ext.grid.Panel', {

    renderTo: Ext.getBody(),

    frame: true,

    store: Books,

    350,

    height: 400,

    title: 'Books',

    features: [Ext.create('Ext.grid.feature.Grouping',{

    groupHeaderTpl: 'topic: {name} ({rows.length} Book{[values.rows.length > 1 ? "s" : ""]})'

    })],

    columns: [{

    text: 'Name',

    flex: 1,

    dataIndex: 'name'

    },{

    text: 'Topic',

    flex: 1,

    dataIndex: 'topic'

    }]

     
    });
     
    通过上面的代码片段,我们可以看到要使用Ext.grid.feature.Grouping还要在Store中设置groupField属性来设置分组字段名。然后通过groupHeaderTpl属性来设置分组头,{name}就是访问groupField指向的字段的值,{rows.length}就是组记录数目。
     
    5.1.2.2. Ext.grid.feature.Summary                                            
         Ext.grid.feature.Summary实在Grid所有记录行的最后插入总结行。该类继承于Ext.grid.feature.AbstractSummary类。

    Ext.create('Ext.grid.Panel', {

    renderTo: Ext.getBody(),

    frame: true,

    store: Books,

    350,

    height: 300,

    title: 'Books',

    features: [{

    ftype: 'summary'

    }],

    columns: [{

    text: 'Name',

    flex: 1,

    dataIndex: 'name',

    summaryType: 'count',

    summaryRenderer: function(value){

    return Ext.String.format('{0} book{1}',

    value, value !== 1 ? 's' : '');

    }

    },{

    text: 'Topic',

    flex: 1,

    dataIndex: 'topic'

    }]

    }); 

    从上述代码片段可知道,features配置项中我们只需配置{ftype: "summary"},然后在需要作归纳总结的列中配置summaryType和summaryRenderer即可(也就是说,不配置这两项,那么该列将不出现归纳总结的内容)。
    summaryType: 内置值有count,average,sum,min,max,可以赋形式为function(records){return "输出内容";}的方法,参数records为model实例数组;
    summaryRenderer: 用于设置总结列的呈现样式,可赋形式为function(value, summaryValue, field){return "呈现内容";}的方法,参数value是归纳总结后的值(就是经过summaryType处理后的值),参数summaryValue是所有的记录,参数field是Model实例的当前总结列的列名。
    效果如下:
     
    5.1.2.3. Ext.grid.feature.GroupingSummary                              
         Ext.grid.feature.GroupingSummary是在Ext.grid.feature.Grouping和Ext.grid.feature.Summary的基础上,为每一个分组添加了一行总结行。具体代码如下:

    Ext.create('Ext.grid.Panel', {

    renderTo: Ext.getBody(),

    frame: true,

    store: Books,

    350,

    height: 400,

    title: 'Books',

    features: [{

    groupHeaderTpl: 'Topic: {name}',

    ftype: 'groupingsummary'

    }],

    columns: [{

    text: 'Name',

    flex: 1,

    dataIndex: 'name',

    summaryType: 'count',

    summaryRenderer: function(value){

    return Ext.String.format('{0} book{1}',

    value, value !== 1 ? 's' : '');

    }

    },{

    text: 'Topic',

    flex: 1,

    dataIndex: 'topic'

    }]

     
    }); 
     
    5.1.2.4. Ext.grid.feature.RowBody                                      
         该特性会在每行的底部插入一个<tr><td><div></div></td></tr>,供我们现实额外的信息。
    Ext.create('Ext.grid.Panel', {
    renderTo: Ext.getBody(),
    frame: true,
    store: Books,
    350,
    height: 300,
    title: 'Books',
    features: [{
    ftype: 'rowbody',
    getAdditionalData: function(data, idx, record, orig) {
    return {
    rowBody: Ext.String.format(
    '<div>->topic:<span> {0}</span></div>',
    data.topic)
    };
    }
    }],

    columns: [{

    text: 'Name',

    flex: 1,

    dataIndex: 'name'

    }]

     
    }); 
    使用了rowBody特性后必须要定义getAdditionalData属性,否则rowBody将不起作用。getAdditionalData值为形如
    function(data, rowIndex, record, orig){
         ........ 
         return {
              rowBody: "额外信息的展现HTML标签",
              rowBodyCls: "额外信息的展现的CSS样式",
              rowBodyColspan: 合并列数
         };
    },其中参数data为为该行的数据,参数rowIndex为行索引,参数record为该行的model对象,参数orig代表原始的消息对象。
    注意:当设置了rowBody特性后,Grid对象会有rowbodyclick、rowbodydbclick和rowbodycontextmenu三个事件可供订阅。
     
    5.1.3. Grid Plugins                                          
         Extjs4中引入了plugin包,其中包含Editing、CellEditing、RowEditing、HeaderResizing和DragDrop五个类。Editing类是一个提供通用方法和属性给可编辑Grid的抽象类。CellEditing和RowEditing是Editing的子类。
    (译者语:本人对于features和plugins的理解是,两者都是Grid的插件,但features与Grid的耦合性更大,如Summary Feature会直接影响到Grid的Columns的配置;而plugins与Grid的耦合性较小,是在Grid上再加一层外衣,不用修改Grid的配置)
    (译者语:对于Grid Plugins这一章本人并没有太多实践经验,因为在开发lppExt(一个搭建在Extjs框架之上,旨在更高效地开发各种管理系统的框架)时为求通用性很少采用Grid Plugins,本节内容均以原文内容为主)
     
    5.1.3.1. Ext.grid.plugin.CellEditing                              
         CellEditing插件可以让我们编辑Grid中特定的单元格。但我们点击某个可编辑的单元格时,就会呈现编辑器(editor)并供我们编辑单元格的值。
    下面是实例:
    Ext.define('Contact', {
    extend: 'Ext.data.Model',
    fields: ['name', 'email','phone']
    });
    var Contacts = Ext.create('Ext.data.Store', {
    model: 'Contact',
    data: [
    {name: 'Loiane', email: 'me@loiane.com', phone: '1234-5678'},
    {name: 'Peter', email: 'peter@email.com', phone: '2222-2222'},
    {name: 'Ane', email: 'ane@email.com', phone: '3333-3333'},
    {name: 'Harry', email: 'harry@email.com', phone: '4444-4444'},
    {name: 'Camile', email: 'camile@email.com', phone: '5555-5555'}
    ]
    });
     
     

    Ext.create('Ext.grid.Panel', {

    renderTo: Ext.getBody(),

    frame: true,

    store: Contacts,

    350,

    title: 'Contacts',

    selType: 'cellmodel',

    columns: [{

    text: 'Name',

    flex: 1,

    dataIndex: 'name'

     
    },{

    text: 'Email',

    flex: 1,

    dataIndex: 'email',

    editor: {

    xtype:'textfield',

    allowBlank:false

    }

    },{

    text: 'Phone',

    flex: 1,

    dataIndex: 'phone',

    editor: {

    xtype:'textfield',

    allowBlank:false

    }

    }],

    plugins: [

    Ext.create('Ext.grid.plugin.CellEditing', {

    clicksToEdit: 1

    })

    ]

     
    });
    上述代码中,我们需要注意下列几点:
    1. 除了plugins属性设置为CellEditing外,我们还要设置clicksToEdit属性。clicksToEdit属性表示用户点击单元格多少次会进入编辑模式;
    2. 要通过配置columns属性中各列的editor属性来决定该列是否为可编辑列,editor的值类型为Ext.form.field.Field。只有配置了editor属性的列,在点击其单元格时才可进入编辑模式;
    3. 另外我们还要配置selType为cellModel,从而使选择模式改为可选择单元格。该属性默认为rowModel,选择模式为选择一整行。
     
    5.1.3.2. Ext.grid.plugins.RowEditing                                    
         RowEditing插件让我们可对特定的行进行编辑。但我们点击某一行时,该行就转换为编辑模式了。
    代码如下:

    Ext.create('Ext.grid.Panel', {

    renderTo: Ext.getBody(),

    frame: true,

    store: Contacts,

    350,

    title: 'Contacts',

    selType: 'rowmodel',

    columns: [{

    text: 'Name',

    flex: 1,

    dataIndex: 'name'

    },{

    text: 'Email',

    flex: 1,

    dataIndex: 'email',

    editor: {

    xtype:'textfield',

    allowBlank:false

    }

    },{

    text: 'Phone',

    flex: 1,

    dataIndex: 'phone',

    editor: {

    xtype:'textfield',

    allowBlank:false

     
    }

    }],

    plugins: [

    Ext.create('Ext.grid.plugin.RowEditing', {

    clicksToEdit: 1

    })

    ]

     
    }); 
    与CellEditing一样,我们也要设置clicksToEdit属性。而且要为可编辑列配置editor属性。而selType要设置为rowModel
     
    5.1.3.3. 保存数据到服务器端                                           
         为了将操作结果保存到服务器端,我们需要修改Store来支持CRUD操作,具体代码如下:

    var Contacts = Ext.create('Ext.data.Store', {

    model: 'Contact',

    proxy: {

    type: 'ajax',

    api: {

    read : 'contact/view.php',

     
    create : 'contact/create.php',

    update: 'contact/update.php',

    destroy: 'contact/delete.php'

    },

    reader: {

    type: 'json',

    root: 'data',

    successProperty: 'success'

    },

    writer: {

    type: 'json',

    writeAllFields: true,

    encode: false,

    root: 'data'

    }

    }

     
    }); 
    我们想在工具栏中添加“新增”和“删除按钮”,代码如下:

    var rowEditor = Ext.create('Ext.grid.plugin.RowEditing', {

    clicksToEdit: 1

     
    })
     

    var grid = Ext.create('Ext.grid.Panel', {

    //other config options

    plugins: rowEditor,

    dockedItems: [{

    xtype: 'toolbar',

    items: [{

    text: 'Add',

    handler : function() {

    rowEditor.cancelEdit();

    // Create a record instance through the ModelManager

    var r = Ext.ModelManager.create({

    name: 'New Contact',

    email: 'newcontact@email.com',

    phone: '1111-1111'

    }, 'Contact');

    Contacts.insert(0, r);

    rowEditor.startEdit(0, 0);

    }

    },{ 

    text: 'Delete',

    handler: function() {

    var sm = grid.getSelectionModel();

    rowEditor.cancelEdit();

    Contacts.remove(sm.getSelection());

    if (Contacts.getCount() > 0) {

         sm.select(0);

    }

    }

    }]

    }]

     
    }); 
    此时我们对Grid的任何修改将暂时保存在客户端的Store中,要保存到服务端就要调用Contacts.sync()了。
    若打算每次操作后马上将操作结果保存到服务端,就要为Contacts配置autoSync属性为true了。
     
    5.1.3.4. 无限滚动                                                  
         (译者语:因没有在API文档中找到对应的配置项说明,并实践中也没有成功过,所以不打算翻译该节内容,若大家成功实现该功能,请告之,谢谢)
     
    5.2. Tree                                                      
         和Grid一样Tree在Extjs4中被大大地简化了。Tree和Grid一样是Ext.panel.Table的子类,也就是说Grid中大部分能使用的功能,同样能在Tree中使用。
    我们先回顾一下如何在Extjs3中创建一棵简单的Tree吧

    new Ext.tree.TreePanel({

    renderTo: 'tree-example',

    title: 'Simple Tree',

    200,

    rootVisible: false,

    root: new Ext.tree.AsyncTreeNode({

    expanded: true,

    children: [

    { text: "Menu Option 1", leaf: true },

    { text: "Menu Option 2", expanded: true,

    children: [

    { text: "Sub Menu Option 2.1", leaf: true },

    { text: "Sub Menu Option 2.2", leaf: true}

    ] },

    { text: "Menu Option 3", leaf: true }

    ]

    })

     
    }); 
    而在Extjs4中,我们按如下方式创建一棵简单树

    Ext.create('Ext.tree.Panel', {

    title: 'Simple Tree',

    200,

    store: Ext.create('Ext.data.TreeStore', {

    root: {

    expanded: true,

    children: [

    { text: "Menu Option 1", leaf: true },

    { text: "Menu Option 2", expanded: true,

    children: [

    { text: "Sub Menu Option 2.1", leaf: true },

    { text: "Sub Menu Option 2.2", leaf: true}

    ] },

     
    { text: "Menu Option 3", leaf: true }

    ]

    }

    }),

    rootVisible: false,

    renderTo: 'tree-example'

     
    }); 
    两者效果图一样的:
    在Extjs4中我们可以看到三个与Tree相关的类:
    1. NodeInterface:对Node API的封装,表示每一个数节点(译者语:使用上与Model差不多);
    2. Tree:维护各个NodeInterface实例的关系;
    3. TreeStore:Store的子类,专门用于配置Tree的数据源。
     
    5.2.1. Drag-and-drop and sorting                                  
         拖拽在重新排列树节点位置时十分有用。通过下面的代码我们可以实现拖拽特性:

    Ext.create('Ext.tree.Panel', {

    store: store,

    viewConfig: {

    plugins: {

    ptype: 'treeviewdragdrop'

         }

    },

    //other properties

     
    }); 

    var store = Ext.create('Ext.data.TreeStore', {

    proxy: {

    type: 'ajax',

    api: {

    read : '../data/drag-drop.json',

    create : 'create.php'

    }

    },

    writer: {

    type: 'json',

    writeAllFields: true,

    encode: false

    },

    autoSync:true

     
    }); 
     
    而实现树节点排序代码如下:

    Ext.create('Ext.data.TreeStore', {

    folderSort: true,

    sorters: [{

    property: 'text',

    direction: 'ASC'

    }]

     
    });
    (译者语:本人觉得树节点排序的功能不大实用)
     
    5.2.2. Check Tree                                        
    要实现可复选的树是一件十分简单的事情,不信请看下列实例吧:
    这是树节点的数据

    [{

    "text": "Cartesian",

    "cls": "folder",

    "expanded": true,

    "children": [{

    "text": "Bar",

    "leaf": true,

    "checked": true

    },{

    "text": "Column",

    "leaf": true,

    "checked": true

    },{

    "text": "Line",

    "leaf": true,

    "checked": false

    }]

    },{

    "text": "Gauge",

    "leaf": true,

    "checked": false

    },{

    "text": "Pie",

         "leaf": true, 

    "checked": true

     
    }] 
     
    操作代码如下:

    var store = Ext.create('Ext.data.TreeStore', {

    proxy: {

    type: 'ajax',

    url: 'data/check-nodes.json'

    },

    sorters: [{

     
    property: 'leaf',

    direction: 'ASC'

    }, {

    property: 'text',

    direction: 'ASC'

    }]

    });

    Ext.create('Ext.tree.Panel', {

    store: store,

    rootVisible: false,

    useArrows: true,

    frame: true,

    title: 'Charts I have studied',

    renderTo: 'tree-example',

    200,

    height: 250

     
    });
    效果如下:
     
     
    5.2.3. Tree Grid                                            
         在Extjs3中Tree Grid作为额外组件的形式被使用。而在Extjs4中它已变成原生API了。下面我们通过实例来学习吧!

    Ext.define('Book', {

     
    extend: 'Ext.data.Model',

    fields: [

    {name: 'book', type: 'string'},

    {name: 'pages', type: 'string'}

    ]

    });

    var store = Ext.create('Ext.data.TreeStore', {

    model: 'Book',

    proxy: {

    type: 'ajax',

    url: 'data/treegrid.json'

    },

    folderSort: true

     
    }); 
    到此我们已经定义数据源了,下面我们看Tree Grid组件的使用

    Ext.create('Ext.tree.Panel', {

    title: 'Books',

    500,

    height: 300,

    renderTo: Ext.getBody(),

    collapsible: true,

    useArrows: true,

    rootVisible: false,

    store: store,

    multiSelect: true,

    singleExpand: true,

    columns: [{

    xtype: 'treecolumn',

    text: 'Task',

    flex: 2,

    sortable: true,

    dataIndex: 'task'

    },{

    text: 'Assigned To',

    flex: 1,

    dataIndex: 'user',

    sortable: true

    }]

     
    });
    上面的代码中高亮部分columns属性和Ext.grid.Panel的columns属性是一样的。而要注意的是第一列的列类型为treecolumn,那么这列就是可展开的树节点列了。
     
    效果如下:
     
    5.3. Form                                            
         Ext.form.Panel提供一个form的容器。我们通常使用form来管理数据。在Extjs4中form由Fields、FieldContainer、FieldSet、Label和Actions组成。下面我们先通过实例在学习Fields。
       
    5.3.1. Form fields                                              
         Extjs4引入了Ext.form.field包,所有的Form field都属于该包。我们通过实例来看各个field的效果吧

    Ext.create('Ext.form.Panel', {

    frame: true,

    title: 'Form Fields',

    340,

    bodyPadding: 5,

    renderTo: 'form-example',

    fieldDefaults: {

    labelAlign: 'left',

    labelWidth: 90,

    anchor: '100%'

    },

    items: [{

    xtype: 'hiddenfield', //1

    name: 'hiddenfield1',

    value: 'Hidden field value'

    },{

    xtype: 'displayfield', //2

    name: 'displayfield1',

    fieldLabel: 'Display field',

    value: 'Display field <span style="color:red;">value</span>'

    },{

    xtype: 'textfield', //3

    name: 'textfield1',

    fieldLabel: 'Text field',

    value: 'Text field value'

    },{

    xtype: 'textfield', //4

    name: 'password1',

    inputType: 'password',

    fieldLabel: 'Password field'

    },{

    xtype: 'textareafield', //5

    name: 'textarea1',

    fieldLabel: 'TextArea',

    value: 'Textarea value'

    },{

     
    xtype: 'filefield', // 6

    name: 'file1',

    fieldLabel: 'File upload'

    },{

    xtype: 'timefield', //7

    name: 'time1',

    fieldLabel: 'Time Field',

    minValue: '8:00 AM',

    maxValue: '5:00 PM',

    increment: 30

    },{

    xtype: 'datefield', //8

    name: 'date1',

    fieldLabel: 'Date Field',

    value: new Date()

    },{

    xtype: 'combobox', //9

    fieldLabel: 'Combobox',

    displayField: 'name',

    store: Ext.create('Ext.data.Store', {

    fields: [

    {type: 'string', name: 'name'}

    ],

    data: [

    {"name":"Alabama"},

    {"name":"Alaska"},

    {"name":"Arizona"},

    {"name":"Arkansas"},

    {"name":"California"}

    ]

    }),

    queryMode: 'local',

    typeAhead: true

    },{

    xtype: 'numberfield',

    name: 'numberfield1', //10

    fieldLabel: 'Number field',

    value: 20,

    minValue: 0,

    maxValue: 50

    },{

    xtype: 'checkboxfield', //11

    name: 'checkbox1',

    fieldLabel: 'Checkbox',

     
    boxLabel: 'box label'

    },{

    xtype: 'radiofield', //12

    name: 'radio1',

    value: 'radiovalue1',

    fieldLabel: 'Radio buttons',

    boxLabel: 'radio 1'

    },{

    xtype: 'radiofield', //13

    name: 'radio1',

    value: 'radiovalue2',

    fieldLabel: '',

    labelSeparator: '',

    hideEmptyLabel: false,

    boxLabel: 'radio 2'

    },{

    xtype: 'multislider', //14

    fieldLabel: 'Multi Slider',

    values: [25, 50, 75],

    increment: 5,

    minValue: 0,

    maxValue: 100

    },{

    xtype: 'sliderfield', //15

    fieldLabel: 'Single Slider',

    value: 50,

    increment: 10,

    minValue: 0,

    maxValue: 100

    }]

     
    }); 
    上述代码片段中,我们设置了fieldDefaults属性。该属性会应用到所有label实例的field中(即继承Ext.form.field.Base或Ext.form.FieldContainer的类)。这里我们设置了所有field的labelWidth为90px,而field将占用容器100%的宽度。
    效果图如下:
    下面我们来学习各种field吧!
    1. hidden field(xtype:"hiddenfield"):用于保存不向用户显示但需要保存并发送到服务端的内容。例如Id,我们并不想将Id值向用户显示,但在执行更新等操作时我们需要将Id值发送到服务端;
    2. display field(xtype:"displayfield"):用于显示只读内容;
    3. text field(xtype:"textfield"):用于输入简单文本内容;若inputType设置为password就会变成密码输入框;
    4. textarea(xtype:"textareafield"):用于输入多行简单文本内容,是textfield的子类;
    5. field upload field(xtype:"filefield"):用于文件上传;
         以下为继承Trigger类的field,其中共有Picker类型和Spinner类型的field。Picker类型的field会有一个按钮,当点击按钮时就会弹出一个供选择值的弹窗。而Spinner类型的field会有个滑动块来选择值。
    6. time field(xtype:"timefield"):通过配置minValue和maxValue属性来限定最小和最大的时刻。如上述例子中分别设置最小时刻为8:00 AM和最大时刻5:00 PM。并且我们可以通过increment设置时刻间隔(例子中设置为30分钟);
    7. date field(xtype:"datefield"):用于设置日期。实例中设置默认值为当前日期;
    8. combox field(xtype:"combobox"或xtype:"combo"):下拉列表,需要使用Store做为数据源;
    9. number field(xtype:"numberfield"):用于输入纯数字值;若不想显示向上向下按钮的话就要设置以下的属性
         hideTrigger:true,
         keyNavEnabled: false,
         mouseWheelEnabled: false
    10. checkbox(xtype:"checkboxfield"或xtype:"checkbox");
    11. radio field(xtype:"radiofield"或xtype:"radio"):checkbox的子类;
    12. multi-slider field(xtype:"multislider"):用于在某个数值范围内选择多个值;
    13. single slider field(xtype:"slider"或xtype:"sliderfield"):用于在某个数值范围内选择单个值。
     
    5.3.2. Validation                                              
         对用户输入的不信任我想是一种软件开发的法则了,那么对用户输入的验证是必不可少的。下面我们就学习以下吧!

    Ext.create('Ext.form.Panel', {

    frame: true,

    title: 'Form Fields Validation',

    340,

    bodyPadding: 5,

    renderTo: 'form-example',

    fieldDefaults: {

    labelAlign: 'left',

    labelWidth: 90,

    anchor: '100%',

    msgTarget: 'under'

    },

    items: [{

    xtype: 'textfield',

    name: 'textfield1',

    fieldLabel: 'Required',

    allowBlank: false //1

    },{

    xtype: 'textfield',

    name: 'textfield2',

    fieldLabel: 'Min 2',

    minLength: 2 //2

    },{

    xtype: 'textfield',

    name: 'textfield3',

    fieldLabel: 'Max 5',

    maxLength: 5 //3

     
    },{

    xtype: 'textfield',

    name: 'textfield7',

    fieldLabel: 'Regex - Phone',

    regex: /^d{3}-d{3}-d{4}$/, //4

    regexText: 'Must be in the format xxx-xxx-xxxx'

    },{

    xtype: 'textfield',

    name: 'textfield4',

    fieldLabel: 'Email',

    vtype: 'email' //5

    },{

    xtype: 'textfield',

    name: 'textfield5',

    fieldLabel: 'Alpha',

    vtype: 'alpha' //6

    },{

    xtype: 'textfield',

    name: 'textfield6',

    fieldLabel: 'AlphaNum',

    vtype: 'alphanum' //7

    },{

    xtype: 'textfield',

    name: 'textfield6',

    fieldLabel: 'Url',

    vtype: 'url' //8

    },{

    xtype: 'textfield',

    name: 'textfield8',

    fieldLabel: 'Custom: IP Address',

    vtype: 'IPAddress' //9

    }]

     
    }); 
    当我们验证某个输入为不合法时就需要将错误信息反馈给用户,而msgTarget就是可以配置错误信息是在field的side、under还是top显示。
    验证的类型有:
    1. allowBlank:设置是否允许输入空内容;
    2. maxLength:设置输入内容的最长字数;
    3. minLength:设置输入内容的最短字数;
    4. regex:设置正在表达式来验证输入内容;
    5. vtype:内置的验证规则(alpha,alphanum,email,url),用于限制输入和验证输入内容。当然我们可以自定义验证规则

    Ext.apply(Ext.form.field.VTypes, {

         IPAddress: function(v) {

         return /^d{1,3}.d{1,3}.d{1,3}.d{1,3}$/.test(v););

         },

         IPAddressText: 'Must be a numeric IP address',

         IPAddressMask: /[d.]/i

         });
    这样我们就可以vtype:"IPAddress"来用该验证规则来限制输入和验证输入内容了。
     
    5.3.3. Form label                                       
         label是在form中呈现简单文本内容的组件。代码如下:

    Ext.create('Ext.form.Panel', {

    title: 'Form with Label',

    100,

    bodyPadding: 10,

    renderTo: 'form-example',

    items: [{

    xtype: 'label',

    forId: 'myFieldId',

    text: 'Just a Label',

    margins: '0 0 0 10'

    }]

     
    }); 
     
    5.3.4. Actions(操作)                                          
         对于form我们一般执行加载数据和提交数据两类操作。下面我们通过实例来学习:

    Ext.create('Ext.form.Panel', {

    title: 'Book Info',

    renderTo: 'form-example',

    300,

    bodyPadding: 5,

    fieldDefaults: {

    labelAlign: 'left',

    labelWidth: 90,

    anchor: '100%'

    },

    items: [{

    xtype: 'hiddenfield',

    name: 'bookId'},{

    xtype: 'textfield',

    name: 'bookName',

    fieldLabel: 'Title'

    },{

    xtype: 'textfield',

    name: 'bookAuthor',

    fieldLabel: 'Author'

    }],

    buttons: [{

    text: 'Load',

    handler: function() {

    var form = this.up('form').getForm();

    form.load({

    url: 'data/form.json',

    failure: function(form, action) {

    Ext.Msg.alert("Load failed", action.result. errorMessage);

    }

    });

    }

    },{

    text: 'Submit',

    handler: function() {

    var form = this.up('form').getForm();

    form.submit({

    url: 'form-submit.php',

    waitMsg: 'Sending the info...',

    success: function(fp, o) {

    Ext.Msg.alert('Success', 'Form submitted.');

    }

    });

    }

    }]

     
    }); 
         这里我们通过this.up("form").getForm()的方式得到Ext.form.Basic类,然后才能对表单进行数据合法性验证、加载数据和提交数据等操作。
         加载数据时我们需要调用load操作,具体设置请参考API文档中的Ext.form.action包下的类。
    加载数据的格式如下:

    {

    success: true,

    data: {

    bookId: 10,

    bookName: "Ext JS 4 First Look",

    bookAuthor: "Loiane Groner"

    }

     
     
    5.4. 总结                                                    
         通过本章的学习,我想大家已经对Grid、Tree和Form的使用有一定的了解。当然这里只是简单的介绍它们,要想用得好还是要靠大家多实践的!
  • 相关阅读:
    使用golang访问kubebernetes
    使用 Rancher 管理现有 Kubernetes 集群
    Running powershell scripts during nuget package installation and removal
    How to Create, Use, and Debug .NET application Crash Dumps in 2019
    寻找写代码感觉(一)之使用 Spring Boot 快速搭建项目
    Selenium+Java之解决org.openqa.selenium.InvalidArgumentException: invalid argument报错问题
    Selenium环境搭建
    关于Xpath定位方法知道这些基本够用
    Web自动化之浏览器启动
    【翻译】编写代码注释的最佳实践
  • 原文地址:https://www.cnblogs.com/niejunchan/p/4998512.html
Copyright © 2011-2022 走看看