Welcome to svlab

Member Login

Lost your password?

Not a member yet? Sign Up!

Предыдущий пост Следующий пост
28 Jan 2017

 

ExtJS начиная с версии 5 для связки полей в виде и модели использует механизм Binding.

В данном учебном материале приведен пример CRUD на базе формы и таблицы.

В программе используются следующие классы:

MyApp.model.Person (Класс записи в модели сущности персоны)

MyApp.store.Personnel (Класс хранилища записей в модели с начальными данными)

MyApp.view.main.MainModel (Класс модели вида с механизмом Binding)

MyApp.view.main.Form (Класс формы, где поля формы связаны с моделью механизмом Binding)

MyApp.view.main.List (Класс таблицы, где поля записей в таблице связаны с моделью механизмом Binding)

MyApp.view.main.MainController (Класс контроллера, определяющий привязанные обработчики действий к виду)

MyApp.view.main.Main (Класс панели вида с размещенным на ней формой и таблицей)

MyApp.Application (Класс приложения)

 

Исходный код:

MyApp.model.Person:

Ext.define('MyApp.model.Person', {
    extend: 'Ext.data.Model',
 
    alias: 'model.person',
 
    fields: [
        'id', 'name', 'title', 'description', 'date'
    ]
});

MyApp.store.Personnel:

Ext.define('MyApp.store.Personnel', {
    extend: 'Ext.data.Store',
 
    alias: 'store.personnel',
 
    requires: [
        'MyApp.model.Person'
    ],
 
    fields: [
        'id', 'name', 'title', 'description', 'date'
    ],
 
    data: {
        items: [{
            id: 1,
            name: 'Jean Luc1',
            title: 'File1',
            description: 'Content1',
            date: '01/01/2015'
        }, {
            id: 2,
            name: 'Jean Luc2',
            title: 'File2',
            description: 'Content2',
            date: '02/01/2015'
        }, {
            id: 3,
            name: 'Jean Luc3',
            title: 'File3',
            description: 'Content3',
            date: '03/01/2015'
        }, {
            id: 4,
            name: 'Jean Luc4',
            title: 'File4',
            description: 'Content4',
            date: '04/01/2015'
        }]
    },
 
    proxy: {
        type: 'memory',
        reader: {
            type: 'json',
            rootProperty: 'items'
        }
    }
});

MyApp.view.main.MainModel:

Ext.define('MyApp.view.main.MainModel', {
    extend: 'Ext.app.ViewModel',
 
    alias: 'viewmodel.main',
 
    stores: {
        persons: {
            type: 'personnel',
            autoLoad: true
        }
    },
 
    formulas: {
        person: {
            bind: {
                bindTo: '{personGrid.selection}',
                deep: true
            },
            get: function (record) {
                return record;
            },
            set: function (record) {
                if (!record.isModel) {
                    record = this.get('persons').getById(record.id);
                    this.set('person', record);
                }
            }
        }
    }
});
 
В данном классе обьявлена связь хранилища сущностей персон с полем в модели:
stores: {
        persons: {
            type: 'personnel',
            autoLoad: true
        }
    },
 
Также приведен механиз Binding для связи выделенной строки таблицы с вычесляемым полем person модели:
formulas: {
        person: {
            bind: {
                bindTo: '{personGrid.selection}',
                deep: true
            },

MyApp.view.main.Form:

Ext.define('MyApp.view.main.Form', {
    extend: 'Ext.form.Panel',
    xtype: 'mainform',
 
    viewModel: 'main',
 
    requires: [
        'MyApp.view.main.MainModel'
    ],
 
    title: 'Edit form',
 
    modelValidation: true,
 
    layout: 'anchor',
    defaults: {
        labelWidth: 100,
        selectOnFocus: true,
        anchor: '95%',
        allowBlank: false,
        style: 'margin: 30px 0px 0px 30px;'
    },
 
    items: [{
        xtype: 'numberfield',
        name: 'id',
        fieldLabel: 'ID',
        bind: '{person.id}'
    }, {
        xtype: 'textfield',
        name: 'name',
        fieldLabel: 'Name',
        bind: '{person.name}'
    }, {
        xtype: 'textfield',
        name: 'title',
        fieldLabel: 'Title',
        anchor: '95%',
        bind: '{person.title}'
    }, {
        xtype: 'textareafield',
        name: 'description',
        fieldLabel: 'Decription',
        anchor: '95%',
        bind: '{person.description}'
    }, {
        xtype: 'datefield',
        name: 'date',
        fieldLabel: 'Date',
        maxValue: new Date(),
        bind: '{person.date}'
    }, {
        xtype: 'panel',
        border: false,
        anchor: '100%',
        height: 100,
        style: '',
        layout: {
            type: 'hbox',
            align: 'middle',
            pack: 'center'
        },
        items: [{
            xtype: 'button',
            minWidth: 70,
            text: 'Save',
            listeners: {
                click: 'saveItem'
            }
        }]
    }]
});
 
В полях таблицы задействован механиз Binding их связи с вычесляемым полем модели person
 items: [{
        xtype: 'numberfield',
        name: 'id',
        fieldLabel: 'ID',
        bind: '{person.id}'
    },... 

В данном поле происходит связь значения value поля со значением person.id вычесляемого поля модели person и его ключом id.

На панели формы добавлена кнопка предназначенная для сохранения значений формы в изменяемую строку таблицы

{
            xtype: 'button',
            minWidth: 70,
            text: 'Save',
            listeners: {
                click: 'saveItem'
            }
        }
 
Обработчик клика по кнопке будет объявлен в контроллере.

MyApp.view.main.List:

Ext.define('MyApp.view.main.List', {
    extend: 'Ext.grid.Panel',
    xtype: 'mainlist',
 
    requires: [
        'Ext.grid.plugin.CellEditing',
        'MyApp.view.main.MainModel',
        'MyApp.store.Personnel'
    ],
 
    plugins: [{
        ptype: 'cellediting'
    }],
    modelValidation: true,
 
    title: 'Personnel',
 
    publishes: ['person'],
 
    bind: {
        store: '{persons}'
    },
 
    reference: 'personGrid',
 
    columns: [{
        text: 'ID',
        dataIndex: 'id',
        editor: {
            bind: '{person.id}',
            selectOnFocus: true
        }
    }, {
        text: 'Name',
        dataIndex: 'name',
        editor: {
            bind: '{person.name}',
            selectOnFocus: true
        }
    }, {
        text: 'Title',
        dataIndex: 'title',
        editor: {
            bind: '{person.title}',
            selectOnFocus: true
        }
    }, {
        text: 'Description',
        dataIndex: 'description',
        flex: 1,
        editor: {
            bind: '{person.description}',
            selectOnFocus: true
        }
    }, {
        text: 'Date',
        dataIndex: 'date',
        xtype: 'datecolumn',
        flex: 1,
        editor: {
            bind: '{person.date}',
            selectOnFocus: true
        }
    }],
 
    listeners: {
        select: 'loadToForm'
    },
 
    tbar: [{
        xtype: 'button',
        text: 'Refresh',
        listeners: {
            click: 'refreshGrid'
        }
    }, '->', {
        xtype: 'button',
        text: 'Add empty',
        listeners: {
            click: 'addItem'
        }
    }, {
        xtype: 'button',
        text: 'Edit',
        listeners: {
            click: 'editItem'
        }
    }, {
        xtype: 'button',
        text: 'Delete selected',
        listeners: {
            click: 'deleteItem'
        }
    }]
});
 
В данном классе установлен механиз Binding для хранилища записей таблицы:
bind: {
        store: '{persons}'
    },
 
Объявление имени таблицы для использования механизма Binding в модели
reference: 'personGrid'
 
Подключен механизм Binding для значений столбцов в изменяемой строке таблицы:
columns: [{
        text: 'ID',
        dataIndex: 'id',
        editor: {
            bind: '{person.id}',
            selectOnFocus: true
        }
    }, ...
В данном случае значение столбца id изменяемой строки связано механизмом Binding с вычесляемым полем person модели и его ключом id.
 
В tbar таблицы добавлены кнопки добавления пустой записи таблицы (обработчик клика addItem находится в контроллере),  редактирование записи таблицы в форме (editItem), удаления записи из таблицы (deleteItem).
 

MyApp.view.main.MainController:

Ext.define('MyApp.view.main.MainController', {
    extend: 'Ext.app.ViewController',
 
    alias: 'controller.main',
 
    loadToForm: function (item, record) {
    },
 
    refreshGrid: function (button) {
        this.doFormButton(button, 'cancel');
    },
 
    saveItem: function (button) {
        this.doFormButton(button, 'save');
    },
 
    addItem: function (button) {
        var vm = this.getViewModel();
 
        var store = vm.getStore('persons');
 
        store.sort({
            property: 'id',
            direction: 'ASC'
        });
        var lastRecord = store.last();
        var record = store.insert(0, {
            id: lastRecord.data.id + 1
        })[0];
        vm.set('person', record);
        store.commitChanges();
    },
 
    editItem: function (button) {
        var mainPanel = button.up('app-main');
        var grid = mainPanel.down('grid');
        var records = grid.getSelectionModel().getSelection();
 
        var record = records[0];
 
        var form = mainPanel.down('form');
        var formvm = form.getViewModel();
 
        form.getForm().setValues(record.data);
    },
 
    deleteItem: function (button) {
        var mainPanel = button.up('app-main');
        var grid = mainPanel.down('grid');
        var records = grid.getSelectionModel().getSelection(),
            title = records[0].data.title;
        var msgText = Ext.String.format(
            "Do you really want to delete item '{0}'?",
            title
        );
        msgText = Ext.util.Format.htmlEncode(msgText);
        Ext.Msg.confirm(
            "Confirmation",
            msgText,
            function (button) {
                if (button != "yes") {
                    return;
                }
                grid.store.remove(records);
            }
        );
    },
 
    doFormButton: function (button, action) {
        var person = this.getViewModel().get('person');
        person.commit();
        person.reject();
    }
});
 
В классе контроллера объявлены обработчики кнопок формы и tbar таблицы:
saveItem, addItem, editItem, deleteItem.
Обработчик saveItem имеет код для получения вычисляемого поля модели person и его сохранения в таблице:
var person = this.getViewModel().get('person');
        person.commit();
        person.reject();
 

Обработчки addItem имеет код для получения хранилища таблицы из модели

var vm = this.getViewModel();
 
var store = vm.getStore('persons');
 
Сортировки записей в таблице по столбцу id:
store.sort({
            property: 'id',
            direction: 'ASC'
        });
Получении последней записи таблицы после сортировки с наибольшим id: 

var lastRecord = store.last();

Вставки пустой строки в таблицу:

var record = store.insert(0, {
            id: lastRecord.data.id + 1
        })[0];
 
Обработчик editItem заносит значения изменяемой строки таблицы в форму:
В обработчике получают выделенную строку таблицы:
var mainPanel = button.up('app-main');
        var grid = mainPanel.down('grid');
        var records = grid.getSelectionModel().getSelection();
 
        var record = records[0];
 
И заносят значения записи в поля формы:
var form = mainPanel.down('form');
        var formvm = form.getViewModel();
 
        form.getForm().setValues(record.data);
 
Обработчик deleteItem удаляет выделенную строку таблицы.
Перед удалением записи таблицы создается диалог подтверждения действия для удаления выделенной строки таблицы:
Ext.Msg.confirm(
            "Confirmation",
            msgText,
            function (button) {
                if (button != "yes") {
                    return;
                }
                grid.store.remove(records);
            }
        );
 

MyApp.view.main.Main:

Ext.define('MyApp.view.main.Main', {
    extend: 'Ext.panel.Panel',
    xtype: 'app-main',
 
    requires: [
        'Ext.plugin.Viewport',
        'Ext.window.MessageBox',
 
        'MyApp.view.main.MainController',
        'MyApp.view.main.MainModel',
        'MyApp.view.main.List',
        'MyApp.view.main.Form'
    ],
 
    controller: 'main',
    viewModel: 'main',
    layout: 'column',
 
    items: [{
        xtype: 'mainlist',
        columnWidth: 0.5
    }, {
        xtype: 'mainform',
        columnWidth: 0.5
    }]
});
 
Данный класс определяет главную панель вида с размещенными на ней таблицей и формой:
 items: [{
        xtype: 'mainlist',
        columnWidth: 0.5
    }, {
        xtype: 'mainform',
        columnWidth: 0.5
    }]
 

MyApp.Application:

Ext.define('MyApp.Application', {
    extend: 'Ext.app.Application',
 
    name: 'MyApp'
});
 
Ext.application({
    name: 'MyApp',
 
    extend: 'MyApp.Application',
 
    requires: [
        'MyApp.view.main.Main'
    ],
 
    mainView: 'MyApp.view.main.Main'
});
 
В данном коде объявлен класс приложения и определено его создание с подключением вида:
mainView: 'MyApp.view.main.Main'.
 
Исходники приложения, а также его работу можно посмотреть на странице:
 

 

SHARE:

#

Post dicussion

Контакты

Для связи svbeat@yandex.ru

  • 1
  • 1