Javascript-форум (https://javascript.ru/forum/)
-   ExtJS (https://javascript.ru/forum/extjs/)
-   -   Как можно разделить main view и listeners? (https://javascript.ru/forum/extjs/52093-kak-mozhno-razdelit-main-view-i-listeners.html)

treasury 03.12.2014 18:31

Как можно разделить main view и listeners?
 
Помогите с архитектурой, допустим у меня есть main view, фрагмент:
items: [
                {
                    xtype: 'dataview',
                    autoScroll: true,
                    id: 'dataview',
                    margin: '10 0 10 10',
                    disableSelection: false,
                    itemSelector: 'div',
                    itemTpl: [
                        '<tpl for=".">',
                        '<table>',
                        '   <tr>',
                        '       <td width=\'200px\'><input type="checkbox" enabled="enabled" value="open" name="comment_status" <tpl if="active">checked="checked"</tpl> />{nm}</td>',
                        '       <td class="configure"></td>',
                        '   </tr>    ',
                        '       </table>',
                        '   ',
                        '</tpl>'
                    ],
                    store: 'CarStore',
                    listeners: {
                        itemclick: {
                            fn: 'onDataviewSelectConfigure',
                            single: false
                        },
                        select: 'onDataviewSelect'

                    }

Здесь у меня прописан listeners, я сейчас здесь же в конце view описываю эти функции:
onDataviewSelect: function(dataview, record, eOpts) {
        console.log("OK");
    },


У меня вопрос каким образом их можно разделить? Т.е. я могу как-то их описать в контроллере? Или хотя-бы во view только в новом файле.

siber-biber 04.12.2014 07:24

вы можете подписаться на эти события в контроллере ..и повесить на них методы любого объекта.
view.on({
    itemclick : this.onDataviewSelectConfigure,
    select : this.onDataviewSelect
    scope : this
});

Infarch 04.12.2014 11:18

В контроллере можно. И даже нужно. Просто указываете что листенеры работают в контроллере и пишете все функции там:

listeners: {
	itemclick: {
		fn: 'onDataviewSelectConfigure',
		single: false
	},
	select: 'onDataviewSelect',
	scope: 'controller' // <------------------
}


А зачем вы пишете "single: false"? Это ведь как бы по умолчанию следует. Другое дело если "true"...

treasury 04.12.2014 11:57

Цитата:

Сообщение от Infarch (Сообщение 344409)
В контроллере можно. И даже нужно. Просто указываете что листенеры работают в контроллере и пишете все функции там:

listeners: {
	itemclick: {
		fn: 'onDataviewSelectConfigure',
		single: false
	},
	select: 'onDataviewSelect',
	scope: 'controller' // <------------------
}


А зачем вы пишете "single: false"? Это ведь как бы по умолчанию следует. Другое дело если "true"...

У меня что-то не получается ни так ни так. Я правильно понимаю, что здесь вы говорите о ViewController? Т.е. если я добавляю во view строчку scope: 'controller' , я говорю что обработчик у меня будет реализован в viewController. Я сделал:
listeners: {
                        itemclick: {
                            fn: 'onDataviewSelectConfigure',
                            scope: 'controller'
                        },
                        select: {
                            fn: 'onDataviewSelect',
                            scope: 'controller'
                        }

                    }

Далее во viewController:
Ext.define('MyApp.view.MainViewController', {
    extend: 'Ext.app.ViewController',
    alias: 'controller.main',

onDataviewSelect: function(dataview, record, eOpts) {
        console.log("OK");
    },
});

Далее в консоле такое: Uncaught TypeError: Cannot read property 'apply' of undefined
Что еще нужно поправить?

treasury 04.12.2014 12:09

Цитата:

Сообщение от siber-biber (Сообщение 344377)
вы можете подписаться на эти события в контроллере ..и повесить на них методы любого объекта.
view.on({
    itemclick : this.onDataviewSelectConfigure,
    select : this.onDataviewSelect
    scope : this
});

Это я не понял как применить( Я так понял это в глобальном контроллере описывать, которые лежат в app/controller?

treasury 04.12.2014 13:57

Написал так в контроллере
Ext.define('MyApp.controller.Main', {
    extend: 'Ext.app.Controller',

    views: ['Main'],

    init: function() {
        this.control({

            'dataview': {
                select : this.onDataviewSelect
    }
        });
    },

    onDataviewSelect: function(dataview, record, eOpts) {
    console.log("OK");
}


});

Но помимо работы события при выборе строки в dataview, еще событие выполняется при инициализации приложения, как это исключить? Спасибо!

treasury 05.12.2014 10:16

Я извиняюсь за назойливость, но все таки что нужно поправить в моем случае, чтобы заработало? Спасибо!

Infarch 05.12.2014 11:04

treasury, вы не там описали скоп. Главный контроллер не трогайте, хендлеры работают во вью контроллере компонента. Вот как надо:
listeners: {
	itemclick: 'onDataviewSelectConfigure',
	select: 'onDataviewSelect',
	scope: 'controller'
}


Скоп описывается для всех листенеров оптом. НО! это касается только главного элемента, к которому подключен контроллер. В дочерних его компонентах скоп не нужен, поиск хендлеров идет в контроллере по умолчанию. Например:
Ext.define("PM.view.settings.process.Show", {
	extend: "Ext.panel.Panel",
	requires: [ "Ext.grid.column.Check" ],
	alias: "widget.settings-process-show",
	controller: "settings-process-show",
	viewModel: { type: "settings-process-showedit" },
	bind: { title: "{model.Name}" },
	items: [
		{ xtype: "gridpanel",
			bind: { store: "{subjectFields}" },
			columns: [
				{ xtype : "checkcolumn", text : "#Active", dataIndex : "Active", disabled: true },
				{ text: "#Name", dataIndex: "Name", flex: 1 }
			]
		},
		{ xtype: "docia-separator" },
		{ xtype: "container",
			layout: "hbox",
			align: "left",
			defaults: {
				width: 75,
				margin: "0 10 0 0"
			},
			items: [
				{ xtype: "button", text: "<< Back", handler: "goBack" },
				{ xtype: "button", text: "Edit", handler: "doEdit" }
			]
		}
	]
	
});


Обратите внимание на кнопки в конце класса. Их хендлеры автоматически ищутся в контроллере, скоп не указываем. Это относится почти к любому дочернему компоненту.

treasury 05.12.2014 15:26

Написал во view как вы сказали:
Ext.define('MyApp.view.Main', {
    extend: 'Ext.container.Viewport',
    alias: 'widget.main',
    xtype: 'main',
.......................................
items: [
                {
                    xtype: 'dataview',
                    autoScroll: true,
                    id: 'dataview',
                    itemId: 'dataview',
                    margin: '10 0 10 10',
                    disableSelection: false,
                    itemSelector: 'div',
                    itemTpl: [],
                    store: 'CarStore',
                    listeners: {
                        itemclick: 'onDataviewSelectConfigure',
                        select: 'onDataviewSelect',
                        scope: 'controller'

}

Далее viewController:
Ext.define('MyApp.view.MainViewController', {
    extend: 'Ext.app.ViewController',
    alias: 'controller.main',

onDataviewSelect: function(dataview, record, eOpts) {
        console.log("OK");
    }

});

Но ничего не поменялось Uncaught TypeError: Cannot read property 'apply' of undefined

Infarch 05.12.2014 17:24

Цитата:

Сообщение от treasury
Написал во view как вы сказали

А кто будет подключать контроллер?
controller: "main" // это где?


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