2013-02-12 50 views
2

对于ExtJS的Sencha文档,我感到非常困惑。该文档从入门指南开始,该指南重点介绍了适用于您的应用程序的类和源代码的合适结构的重要性。但是,提供的示例将打破“入门指南”中规定的所有约定。代码不是分解成适当的Model,Store,View等类文件,而是将示例作为单个文件提供,其中的示例源代码在单独的源文件中不易重复使用。Sencha ExtJS REST风格的网格示例混淆

我开始遵循门户示例(http://docs.sencha.com/ext-js/4-1/#!/example/portal/portal.html),因为这是我想要创建的应用程序。我想增强Portal示例并添加一个屏幕,该屏幕将显示网格并使用RESTful Web服务作为数据后端。我创建了后端,我只是想创建前端。所以我看了一下RESTful示例(http://docs.sencha.com/ext-js/4-1/#!/example/restful/restful.html

我试图将RESTful示例复制到单独类的推荐模式中,例如型号,存储,显示:

型号:

Ext.define('MyLodge.model.Member', { 
    extend: 'Ext.data.Model', 
    fields: [ 
     {name: 'name',  type: 'string'}, 
     {name: 'email',  type: 'string'}, 
     {name: 'href',  type: 'string'} 
    ] 
}); 

商店:

Ext.require('MyLodge.model.Member'); 

Ext.define('MyLodge.store.Members', { 
    autoLoad: true, 
    autoSync: true, 
    model: 'MyLodge.model.Member', 
    proxy: { 
     type: 'rest', 
     url: 'http://localhost:8888/rest/memberapi/members' , 
     reader: { 
      type: 'json', 
      root: 'data' 
     }, 
     writer: { 
      type: 'json' 
     } 
    }, 
    listeners: { 
     write: function(store, operation){ 
      var record = operation.getRecords()[0], 
       name = Ext.String.capitalize(operation.action), 
       verb; 


      if (name == 'Destroy') { 
       record = operation.records[0]; 
       verb = 'Destroyed'; 
      } else { 
       verb = name + 'd'; 
      } 
      Ext.example.msg(name, Ext.String.format("{0} member: {1}", verb, record.getId())); 

     } 
    } 
}); 

查看:

Ext.define('MyLodge.view.content.MemberGrid', { 
    extend: 'Ext.grid.Panel', 
    alias: 'widget.membergrid', 

    initComponent: function(){ 

     var store = Ext.create('MyLodge.store.Members'); 

     Ext.apply(this, { 
      height: this.height, 
      store: store, 
      stripeRows: true, 
      columnLines: true, 
      columns: [{ 
       id  : 'name', 
       text : 'Name', 
       flex: 1, 
       sortable : true, 
       dataIndex: 'name' 
      },{ 
       text : 'E-Mail', 
       width : 150, 
       sortable : true, 
       dataIndex: 'email' 
      },{ 
       text : 'Href', 
       width : 200, 
       sortable : true, 
       dataIndex: 'href' 
      }], 
      dockedItems: [{ 
       xtype: 'toolbar', 
       items: [{ 
        text: 'Add', 
        iconCls: 'icon-add', 
        handler: function(){ 
         // empty record 
         store.insert(0, new MyLodge.model.Member()); 
         rowEditing.startEdit(0, 0); 
        } 
       }, '-', { 
        itemId: 'delete', 
        text: 'Delete', 
        iconCls: 'icon-delete', 
        disabled: true, 
        handler: function(){ 
         var selection = grid.getView().getSelectionModel().getSelection()[0]; 
         if (selection) { 
          store.remove(selection); 
         } 
        } 
       }] 
      }] 
     }); 

     this.callParent(arguments); 
    } 
}); 

但我不知道在哪里把代码控制网格行选择并启用删除按钮:

grid.getSelectionModel().on('selectionchange', function(selModel, selections){ 
    grid.down('#delete').setDisabled(selections.length === 0); 
}); 

此外,当我点击添加按钮我得到以下错误:

Uncaught TypeError: Object [object Object] has no method 'insert'. 

任何帮助,将不胜感激。

回答

1

您正在考虑范围问题。基本上,变量store仅在initComponent函数中定义,因此也在本地函数作用域中定义。 你的处理函数有它自己的范围。它在工具栏按钮的范围内触发。所以如果你在处理程序中说this,它会引用该按钮。因此,您可以说this.up('panel').store - 并为您提供了支持您的网格面板的商店的正确参考。

另一个建议是不要一次实施所有的东西。写一点点,看它是否有效,然后逐渐加入它。

1

RE:文档示例,我同意这很令人沮丧,但没有多少选项。对每个例子进行完全MVC风格的实现不仅会产生繁重的工作,而且可能会使该示例的重点在结构中丢失。

RE:关于在哪里“放置”代码来控制网格的问题,我会建议在control()部分中为网格上的事件设置一个监听器。这将使您可以将视图本身触发的事件处理与视图本身解耦。