Javascript-форум (https://javascript.ru/forum/)
-   ExtJS (https://javascript.ru/forum/extjs/)
-   -   CRUD, или Не все так просто (https://javascript.ru/forum/extjs/49350-crud-ili-ne-vse-tak-prosto.html)

Infarch 08.08.2014 18:33

CRUD, или Не все так просто
 
Здравствуйте.

Я столкнулся с некоторыми странностями при освоении ExtJS5 CRUD. Был бы очень благодарен за подсказки. Итак, мой код:

Ext.define("Communication.model.entity.AoR", {
	extend: "Ext.data.Model",
	idProperty: "id",
	fields: [
		{ name: 'id',
			type: 'int',
			allowNull: true
		},
		"name"
	],
	proxy: {
		type: "ajax",
		reader: {
			type: "json"
		},
		writer: {
			type: "json",
			rootProperty: "data",
			encode: true
		},
		api: {
			create: "/json?cmd=communication.aor.create",
			read: "/json?cmd=communication.aor.read",
			update: "/json?cmd=communication.aor.update",
			destroy: "/json?cmd=communication.aor.destroy"
		}
	}
});

Ext.define("Communication.view.entity.aor.List", {
	extend: "Ext.grid.Panel",
	alias: "widget.entity-aor-list",
	controller: "entity-aor-list",
	title: "My panel",
	viewModel: {
		type: "entity-aor-list"
	},
	columns: [
		{dataIndex: "name", flex: 1, bind: {text: "{hdrName}"}}
	],
	autoLoad: false,
	store: {
		model: "Communication.model.entity.AoR"
	},
	bind: {
		title: "{listTitle}"
	}

});

Ext.define("Communication.view.entity.aor.ListController", {
	extend: "Ext.app.ViewController",
	alias: "controller.entity-aor-list",
	requires: [
		"Ext.Action"
	],
	
	init: function(){
		
		var 
			view = this.getView(),
			store = view.getStore();
			
		store.addListener("load", this.storeLoad, this);
		store.addListener("add", this.storeAdd, this);
		
		// create actions
		this.actionAdd = Ext.create("Ext.Action", {
			text: Communication.L10n.getText("add"),
			disabled: true,
			scope: this,
			handler: this.addItem
		});
		
		this.actionSave = Ext.create("Ext.Action", {
			text: Communication.L10n.getText("save"),
			disabled: true,
			scope: this,
			handler: this.saveData
		});
		
		// add actions
		view.addDocked([
			{ xtype: 'toolbar',
				dock: 'top',
				items: [this.actionAdd, this.actionSave]
			}
		]);
		
		store.load();
	},
	
	addItem: function(){
		var view = this.getView(),
			store = view.getStore(),
			model = new Communication.view.entity.aor.ListModel({
				id: 0,
				name: "Test"
			});
		model.phantom = true;
		model = store.add(model)[0];
	},
	
	storeAdd: function(store, records, index, eOpts){
		this.actionSave.setDisabled(false);
	},
	
	saveData: function(){
		this.getView().getStore().sync();
	},
	
	storeLoad: function(store, records, successful, eOpts){
		this.actionAdd.setDisabled(false);
	}
	
});


Странности начинаются при добавлении записей в стор. Если я не указываю айди при создании модели, или его значение null, то sync() приводит к ошибке: "too much recursion". В примерах, которые мне попадались, я никогда не видел чтоб в новых записях инициализировали айди нулем. Это странность номер один.
Далее, когда я после добавления записи вызываю sync() ничего не происходит. Никаких обращений к серверу. Пытаюсь выставить model.phantom = true - не помогает. Вопрос номер два: как быть?
Еще, новая запись отображается в гриде без этих красных маркеров что показывают состояние dirty. Я пробовал сначала создать запись, а потом посетать поля. Так маркеры отображаются, но... sync() приводит к обращению по адресу update: "/json?cmd=communication.aor.update". Как бы это сделать так, чтобы и новая запись мыла отмаркирована, и операцию происходила правильная?

siber-biber 11.08.2014 07:07

Цитата:

Сообщение от Infarch (Сообщение 324979)
Если я не указываю айди при создании модели, или его значение null, то sync() приводит к ошибке: "too much recursion". В примерах, которые мне попадались, я никогда не видел чтоб в новых записях инициализировали айди нулем.

похоже тут ваши желания идут поперек планов сенчи. с 5й версии они решили что поле id модели должно быть все время заполнено ..они теперь кладут туда по умолчанию сгенерированное значение. возможно отсюда ваши проблемы ..не обнуляйте id.

еще ..я посмотрел на код ..вы создаете экземпляры моделей с одним и тем же значением id:
store = view.getStore(),
			model = new Communication.view.entity.aor.ListModel({
				id: 0, // зачем?
				name: "Test"
			});

так делать нельзя, предполагается что значения в этом поле уникальны

Infarch 11.08.2014 12:08

Ну а что мне там написать при создании новой записи? Айди будет сформирован сервером при вставке в базу. А если я его тут не указываю, то возникает ошибка sync().

Цитата:

Сообщение от Infarch
Далее, когда я после добавления записи вызываю sync() ничего не происходит. Никаких обращений к серверу. Пытаюсь выставить model.phantom = true - не помогает. Вопрос номер два: как быть?

А про это что нибудь посоветуете?

Infarch 11.08.2014 12:56

Все, вопрос снят ) Сам виноват, неправильно указал имя модели при создании. Это вьюмодель, а не данные. Поправил, sync заработал.

siber-biber 11.08.2014 19:20

Цитата:

Сообщение от Infarch (Сообщение 325304)
Ну а что мне там написать при создании новой записи? Айди будет сформирован сервером при вставке в базу. А если я его тут не указываю, то возникает ошибка sync().

вот именно что указывать его не надо, и ошибки при этом быть не должно

Infarch 12.08.2014 11:06

Ну так я уже написал - сам ошибся ) Теперь все работает.

Кстати, на этом форуме можно закрывать темы?


Часовой пояс GMT +3, время: 08:09.