https://github.com/ananddayalan/extjs-by-example-company-directory |
Проект состоит из следующих компонентов:
- Grid panel
- ViewModel
- Model
- Data store and rest proxy
- Layouts and containers
- RowEditing plugins
- Pagination
- REST API in Go
- References
Операции редактирования/добавления выполняются с помощью плагина RowEditing.
Структура проекта:
Самый легкий путь добавить гриду возможности редактирования это использовать плагин RowEditing:
plugins: [{ ptype: 'rowediting', clicksToMoveEditor: 1, autoCancel: false }],
Для того чтобы редактирование заработало надо установить значение свойству editor у столбцов грида:
editor: { xtype: 'textfield', allowBlank: false }
Путем установки правил валидации в эдиторе, плагин RowEditing позволяет ввод только валидных данных в ином случае кнопка Update становится не активной.
В гриде используются два тулбара. Один для пейджинг-тулбара. И один для кнопок ДОБАВИТЬ, УДАЛИТЬ и СОХРАНИТЬ. Эти тулбары состыкованы с гридом через свойство dockedItems. 'dockedItems' - это свойство принадлежащее панели. Оно позволяет подстыковать компоненты слева, справа, сверху или снизу. Можно подстыковать любой компонент, но обычно это тулбары.
Ext.define('CD.view.contactList.ContactList', { extend: 'Ext.panel.Panel', requires: ['CD.view.contactList.ContactListController'], xtype: 'app-contactList', controller: 'contactList', items: [{ cls: 'contact-list', xtype: 'grid', reference: 'contactListGrid', scrollable: true, autoScroll: true, plugins: [{ ptype: 'rowediting', clicksToMoveEditor: 1, autoCancel: false }], listeners: { selectionchange: 'onSelectionChange' }, flex: 1, store: 'contactList', pageSize: 10, title: 'Company Directory', columns: { defaults: { editor: { xtype: 'textfield', allowBlank: false } }, items: [{ text: 'First Name', width: 100, dataIndex: 'fname' }, { text: 'Email', width: 250, dataIndex: 'email', editor: { vtype: 'email' } }, /* Code truncated */ ] }, dockedItems: [{ xtype: 'pagingtoolbar', store: 'contactList', dock: 'bottom', displayInfo: true }, { xtype: 'toolbar', dock: 'top', ui: 'footer', defaults: { cls: 'btn-orange' }, items: ['->', { text: 'Remove', disabled: true, reference: 'btnRemoveContact', listeners: { click: 'onRemove' }, }, /* Code truncated */ ] }] }] });
Пейджинг-тулбар нуждается в сторе чтобы правильно отображать количество страниц.
dockedItems: [{ xtype: 'pagingtoolbar', store: 'contactList', dock: 'bottom', displayInfo: true }, { xtype: 'toolbar', dock: 'top', ui: 'footer', //This sets style to the component. The 'ui' is a property of the component. The default value of this property for all the component is 'default'. defaults: { cls: 'btn-orange' }, items: ['->', { text: 'Remove', disabled: true, //We set disabled by default, and this will be enabled when a row in the grid is selected.Check the onSelectionChange method in the controller. reference: 'btnRemoveContact', listeners: { click: 'onRemove' }, }, // …Code truncated ] }]
Код ViewController очень простой. Он только обрабатывает события добавления, удаления и изменения выделения для вьюхи ContactList. Доступ к гриду из контроллера:
var grid = this.lookupReference('contactListGrid');
Стор получается методом grid.getStore(); или также можно использовать метод Ext.getStore(contactList):
Ext.define('CD.view.contactList.ContactListController', { extend: 'Ext.app.ViewController', alias: 'controller.contactList', views: ['CD.view.contactList.ContactList'], requires: ['CD.store.ContactList'], onSave: function() { //Note, this will trigger one or more calls to the server based on the number of operations performed in the store. Ext.getStore('contactList').save(); }, onSelectionChange: function() { this.lookupReference('btnRemoveContact').enable(); }, onRemove: function() { var grid = this.lookupReference('contactListGrid'); var sm = grid.getSelectionModel(); //This line cancels the row/cell edit if it is active before we remove the item. grid.plugins[0].cancelEdit(); grid.getStore().remove(sm.getSelection()); if (grid.getStore().getCount() > 0) { sm.select(0); } }, onCreate: function() { var grid = this.lookupReference('contactListGrid'); grid.plugins[0].cancelEdit(); // Create a model instance var r = Ext.create('Contact'); grid.getStore().insert(0, r); grid.plugins[0].startEdit(0, 0); } });
Код для модели:
Ext.define('Contact', { extend: 'Ext.data.Model', fields: ['fname', 'lname', 'email', 'address', 'city', 'state', 'phone', 'type'] }); Ext.define('CD.store.ContactList', { extend: 'Ext.data.Store', storeId: 'contactList', model: 'Contact', pageSize: 10, proxy: { type: 'rest', url: 'contactlist', reader: { type: 'json', rootProperty: 'data', totalProperty: 'total' } } }); Ext.create('CD.store.ContactList').load();
Свойство totalProperty позволяет стору узнать общее количество записей и сделать пагинацию.
REST API