ExtJS:指向子元素的dataview itemSelector

时间:2012-02-04 15:23:38

标签: extjs4

我想使用dataview呈现以下层次结构数据:

[{
  id: 1,
  name: 'Parent #1',
  children: [ { id: 11, name: 'Child 1.1' }, { id: 12, name: 'Child 1.2' }]
 },
 {
  id: 1,
  name: 'Parent #1',
  children: [ { id: 21, name: 'Child 2.1' }, { id: 22, name: 'Child 2.2' }]
}]

以下列形式:

Parent #1    <- div with class = x-title
 Child 1.1  <- div with class = x-list-item
 Child 1.2 
Parent #2
 Child 2.1
 Child 2.2

我的dataview tpl配置如下:

  ...
  trackOver: true,
  tpl: new Ext.XTemplate( 
    '<tpl for=".">',
'<div class="x-title">{name}</div>',
    '<tpl for="children">',
    '<div class="x-list-item">{name}</div>',
    '</tpl>',
'</tpl>'
  ),
  ...

问题在于:

  1. itemSelector:'x-list-item'无法正常工作无法读取未定义的属性'internalId'
  2. itemSelector:'x-title'work!
  3. 我想知道是否有可能支持itemSelector指向children元素而不是root级别?

1 个答案:

答案 0 :(得分:3)

稍微扩展DataView后可以。

示例代码:

Ext.create('Ext.Panel', {
    id: 'images-view',
    frame: true,
    collapsible: true,
    width: 535,
    renderTo: 'dataview-example',
    title: 'Simple DataView (0 items selected)',
    items: Ext.create('Ext.view.View', {
        store: store,
        tpl: new Ext.XTemplate( 
            '<tpl for=".">',
                '<div class="x-item x-title">{name}</div>',
                '<tpl for="children">',
                    '<div class="x-item x-item-child">{name}</div>',
                '</tpl>',
            '</tpl>'
        ),
        multiSelect: true,
        height: 310,
        trackOver: true,
        overItemCls: 'x-item-over',
        itemSelector: '.x-item',
        emptyText: 'No images to display',

        onItemSelect: function(record) {
            var node = this._selectedNode; //this.getNode(record);

            if (node) {
                Ext.fly(node).addCls(this.selectedItemCls);
            }
        },

        onItemDeselect: function(record) {
            var node = this._deselectedNode; //this.getNode(record);

            if (node) {
                Ext.fly(node).removeCls(this.selectedItemCls);
            }
        },

        processItemEvent: function(record, item, index, e) {
            if (e.type == "mousedown" && e.button == 0) {
                this._deselectedNode = this._selectedNode;
                this._selectedNode = item;
                console.log(item.innerHTML);
            }
        },

        updateIndexes : function(startIndex, endIndex) {
            var ns = this.all.elements,
                records = this.store.getRange(),
                i, j;

            startIndex = startIndex || 0;
            endIndex = endIndex || ((endIndex === 0) ? 0 : (ns.length - 1));
            for(i = startIndex, j = startIndex - 1; i <= endIndex; i++){
                if (!Ext.fly(ns[i]).is('.x-item-child')) {
                    j++;
                }

                ns[i].viewIndex = i;

                ns[i].viewRecordId = records[j].internalId;
                if (!ns[i].boundView) {
                    ns[i].boundView = this.id;
                }
            }
        }
    })
});

工作样本:http://jsfiddle.net/fU9De/

但是,如果不修改DataView,只需更改数据布局就可以很容易地实现,因为子项是分隔的记录。例如:

[
    {
        id: 1,
        name: 'Parent #1',
        children: [ 11, 12 ]
    },
    { id: 11, name: 'Child 1.1', parentId: 1 }, 
    { id: 12, name: 'Child 1.2', parentId: 1 },
    {
        id: 2,
        name: 'Parent #2',
        children: [ 21, 22 ]
    },
    { id: 21, name: 'Child 2.1', parentId: 2 }, 
    { id: 22, name: 'Child 2.2', parentId: 2 }
]

然后您可以将模板更改为:

new Ext.XTemplate( 
    '<tpl for=".">',
        '<div class="x-item x-title {[!!values.parentId ? "x-item-child" : "x-item-parent"]}">{name}</div>',
    '</tpl>'
),

你可以选择开箱即用的工作。