Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 21.10.2016, 03:14
Аватар для Sogl
Аспирант
Отправить личное сообщение для Sogl Посмотреть профиль Найти все сообщения от Sogl
 
Регистрация: 12.05.2016
Сообщений: 95

Submit формы используя REST API
Всем привет!

Сделал REST ресурс и нарисовал к нему грид и форму редактирования.
Создаю окно редактирования и добавления так:
this.dialog = main.add({
            xtype: 'employees-window',
            viewModel: {
                data: {
                    title: record ? 'Редактирование: ' + record.get('id') : 'Добавить сотрудника'
                },
                links: {
                    theEmployee: record || {
                        type: 'MyApp.model.employees.Employees',
                        create: true
                    }
                }
            },
        });


Сама модель помимо объявления полей содержит вот такое объявление прокси (в store код такой же):
proxy: {
        type: 'api',
        url: MyApp.Global.getApiUrl() + 'api/v1/employees'
    }


В общем, окошко функционирует нормально, выдает пустые поля для добавления и заполняет значения при редактировании. Но возникла проблема уже на этапе добавления записи. Такой код:
onSaveClick: function () {

        //get form
        var form = this.lookupReference('form');

        if (form.isValid()) {

            form.submit();
        }
    }


Выдает ошибку `No URL specified`.
Пока поиск мало информации дал... одни пишут форму сабмитить надо, другие то что с моделью работать через `model.save()`, третьи про ViewModel предлагают... пока никаких результатов у меня.

Так как правильно то добавлять и обновлять записи в store?
Ответить с цитированием
  #2 (permalink)  
Старый 21.10.2016, 10:01
Аватар для Sogl
Аспирант
Отправить личное сообщение для Sogl Посмотреть профиль Найти все сообщения от Sogl
 
Регистрация: 12.05.2016
Сообщений: 95

В общем, выкрутился вот так:
var store = Ext.getStore('employees1');

store.insert(0, this.getViewModel().data.theEmployee);

store.reload();


Что интересно, если выводишь в таблице id, то вместо него выдает мне название класса с цифрой на конце, например, `employees.Employees-7`.
`reload()` перезагружает store уже нормально, хотелось бы понять как id предварительно получить... в примерах это есть, но для раздельных сессий.
Ответить с цитированием
  #3 (permalink)  
Старый 22.10.2016, 06:26
Аспирант
Отправить личное сообщение для XAPuTOH Посмотреть профиль Найти все сообщения от XAPuTOH
 
Регистрация: 17.12.2012
Сообщений: 63

Я сделал базовый клас для формы с кнопками "Сохранить" и "Отменить"
На сохранить навесил примерно такой код:
var record = form.getRecord();
 record.save()


А на отмену закрытие окна(сделал у формы modal:true) формы.

Далее при необходимости редактирования какой либо модели. Создаю новую форму - наследника от базовой. Она содержит только поля формы.
Далее form.setRecord(экземпляр модели)

Очень удобно получилось. Работает уже для кучи моделей. И как правило базового функционала хватает.

Еще у меня форма при клике сохранить вызывает событие save. на него подписывается контроллер который создал форму. И по сохранению записи и закрытии форму он например обновляет дерево или каконибудь грид.
Ответить с цитированием
  #4 (permalink)  
Старый 22.10.2016, 06:49
Аспирант
Отправить личное сообщение для XAPuTOH Посмотреть профиль Найти все сообщения от XAPuTOH
 
Регистрация: 17.12.2012
Сообщений: 63

Про Id.
Если экземпляр модели новый то id по умолчанию именно такой.
Если это экземпляр из грида то у него по логике уже есть id. и он должен сохранится при setRecord/getRecord
Ответить с цитированием
  #5 (permalink)  
Старый 22.10.2016, 15:18
Аватар для Sogl
Аспирант
Отправить личное сообщение для Sogl Посмотреть профиль Найти все сообщения от Sogl
 
Регистрация: 12.05.2016
Сообщений: 95

Сообщение от XAPuTOH
Я сделал базовый клас для формы с кнопками "Сохранить" и "Отменить"
Можете поделиться своим решением? Если код очень объемный, то можно на gist GitHub'а.

Кстати, у вас проверяется правильность ответа сервера? А то вот у меня была ошибка в server-side коде, а при этом в store запись вставилась и в Grid'е отобразилась
Все это до перезагрузки страницы.

Сообщение от XAPuTOH
Еще у меня форма при клике сохранить вызывает событие save. на него подписывается контроллер который создал форму.
А модальное окно отображается поверх всего viewport'а? Тут соседнюю тему я создавал.... если делать форму как дочернюю от Grid'а, то и отображается она поверх Grid'а с оверлеем, а все остальное при этом без оверлея. Выглядит ужасно и нелепо.

Сообщение от XAPuTOH
Если экземпляр модели новый то id по умолчанию именно такой.
Новый экземпляр. Если выводить поле id в таблице и store не обновлять после вставки, то это ужасное значение так там и отобразится
Ответить с цитированием
  #6 (permalink)  
Старый 24.10.2016, 08:18
Аватар для Sogl
Аспирант
Отправить личное сообщение для Sogl Посмотреть профиль Найти все сообщения от Sogl
 
Регистрация: 12.05.2016
Сообщений: 95

А каким образом обновлять запись в store? Не удалять, не вставлять, а именно обновлять...

Не нашел метода update в документации, а мне необходимо именно обновление записи.

Если я пишу вот так:
dialog.getViewModel().data.theEmployee.save();

то событие write у Store попросту не срабатывает, хотя вызов PUT метода в REST происходит и запись обновляется!

p.s. Если попытаться обновить запись вставкой, вот так:
store.insert(index, dialog.getViewModel().data.theEmployee);


То сначала сработает необходимый нам PUT с изменениями... и тут же сразу DELETE этой записи. В итоге запись удаляется

Последний раз редактировалось Sogl, 24.10.2016 в 08:59.
Ответить с цитированием
  #7 (permalink)  
Старый 25.10.2016, 09:58
Аспирант
Отправить личное сообщение для XAPuTOH Посмотреть профиль Найти все сообщения от XAPuTOH
 
Регистрация: 17.12.2012
Сообщений: 63

Такая базовая форма:
Ext.define('common.helpers.BaseForm', {
    extend: 'Ext.form.Panel',
    alias: 'helpers.baseform',

    controller:{
        type:'helpers.baseformcontroller'
    },


    modal:true,
    frame: true,
    closable:true,
    floating:true,
    reference: 'form',
    buttons: [
        {
            formBind: true,
            disabled: true,
            text:'Сохранить',
            handler:'save'
        },
        {
            text: 'Отменить',
            handler: function(){
                this.up('form').close();
            }
        }
    ]
});


Её контроллер:
Ext.define('KSoft.common.helpers.BaseFormController', {
    extend: 'Ext.app.ViewController',
    alias: 'controller.ksoft.helpers.baseformcontroller',

    save:function(){
        var me = this,
            form = this.view,
            record = form.getRecord();
        if (form.isValid()) {
            form.updateRecord(record);
            if(form.extraParams != undefined)
                record.proxy.setExtraParams(form.extraParams);
            record.save({
                success: function(record, operation) {
                    form.fireEvent('save', form); //--- Тут вызываем событие о том что запись успешно сохранена
                    form.close();
                },
                failure: function(record, operation) {
                    //Тут обрабатываем ошибку сохранения.
                }
            });
        } else {
            Ext.Msg.alert('Некорректные данные', 'Введите корректные данные');
        }
    }



});


Вот пример формы:
Ext.define('view.objects.ObjectForm', {
    extend: 'view.helpers.BaseForm',
    alias: 'objectform',

    title:'Объект',
    items: [
        {
            xtype: 'textfield',
            fieldLabel: 'Name',
            name: 'Name'
        }
        {
            xtype: 'textfield',
            fieldLabel: 'Code',
            name: 'Code'
        },
        {
            xtype: 'textfield',
            fieldLabel: 'Icon Cls',
            name: 'iconCls'
        },
        {
            xtype: 'textfield',
            fieldLabel: 'Long Name',
            name: 'LongName'
        },
        {
            xtype: 'textfield',
            fieldLabel: 'Short Name',
            name: 'ShortName'
        },
        {
            xtype: 'numberfield',
            fieldLabel: 'Number Name',
            name: 'IntName'
        },
        {
            xtype: 'checkboxfield',
            fieldLabel: 'isActive',
            name: 'Active',
            checked: true,
            uncheckedValue: false
        },
        {
            xtype: 'hiddenfield',
            name: 'ObjId'
        }
    ]
});


Использую так: Например есть дерево объектов в котором можно добавлять или изменять объекты. Делается это при вызове соответствующих методов контроллера. В которых я уже вызываю непосредственно форму:
var form = new view.objects.ObjectForm;

        form.loadRecord(object);

        form.on('save',this.formSave, this);
        form.show();


После сохранения формы я обновляю соответствующую ветку дерева.
Кстати форма получилась универсальной. Например у меня есть грид в качестве модели которого модель из формы выше. Так я из него вызываю данную форму и меняю свойства модели и т.п.

Окно поверх вьюпорта. так как создается с помощью new.

По поводу обновления.
Я обычно обновляю весь стор после обновления записи. Ну или конкретную ветку если это дерево.
Ответить с цитированием
  #8 (permalink)  
Старый 26.10.2016, 03:46
Аватар для nohuhu
Профессор
Отправить личное сообщение для nohuhu Посмотреть профиль Найти все сообщения от nohuhu
 
Регистрация: 21.05.2015
Сообщений: 321

Сообщение от XAPuTOH Посмотреть сообщение
...
            if(form.extraParams != undefined)
                record.proxy.setExtraParams(form.extraParams);
            ...
В качестве лирического отступления: очень категорически не рекомендую использовать синтаксическую форму if/for/while/etc без скобок {}. И вовсе не из абстрактных соображений навроде красоты кода или кошерности стиля, а просто потому, что в JavaScript это чревато очень мерзкими и крайне трудноуловимыми жуками.

Личный опыт, один раз потратил несколько часов на отлов такого животного. Поймал только благодаря тому, что какой-то несчастный клиент вместе с ребятами из техподдержки бодались две недели и сузили набор вариантов до "в dev версии работает, в боевой сборке не работает".
Ответить с цитированием
  #9 (permalink)  
Старый 26.10.2016, 07:52
Аспирант
Отправить личное сообщение для XAPuTOH Посмотреть профиль Найти все сообщения от XAPuTOH
 
Регистрация: 17.12.2012
Сообщений: 63

Да. Есть, такое.
Поправим. Этот костыль из прошлого вообще убрать нужно.
Пытались к модели привязать дополнительные параметры которые не являются свойствами модели. Решили. а строчки остались.
Ответить с цитированием
  #10 (permalink)  
Старый 28.10.2016, 02:38
Аватар для Sogl
Аспирант
Отправить личное сообщение для Sogl Посмотреть профиль Найти все сообщения от Sogl
 
Регистрация: 12.05.2016
Сообщений: 95

XAPuTOH, у вас и вставка новой записи отрабатывает через этот же код?
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
REST API для сайта на Node js Ashotich Node.JS 2 26.09.2016 23:04
Rest api server(php), кроссдоменные запросы и клиенты на чем угодно torsar Серверные языки и технологии 0 06.05.2016 15:58
rest api client z2312 AJAX и COMET 0 20.01.2015 11:53
Отменить submit формы при нажатии enter MaxStoun Events/DOM/Window 5 07.04.2011 19:00
Как создать проверку вводимого пароля на стойкость, используя API Google. Александр Черепов Элементы интерфейса 4 03.11.2008 02:16