Связанные списки в ExtJs

    Ничего необычного, просто моя реализация одной из самых распространенных задач при создании динамических интерфейсов «связанные списки». Дабы не возникло недопонимания, я имею ввиду два и более элемента Ext.form.ComboBox, выбор значения в одном из которых влияет на подгружаемые значения во втором.



    Предположим есть две модели.
    	Ext.define('User', {
    		extend: 'Ext.data.Model',
    		idProperty: 'id',
    		fields: [
    			{
    				name: 'id',
    				type: 'int'
    			}, {
    				name: 'login',
    				type: 'string'
    			}
    		]
    	});
    
    	Ext.define('UserGroup', {
    		extend: 'Ext.data.Model',
    		idProperty: 'id',
    		fields: [
    			{
    				name: 'id',
    				type: 'int'
    			}, {
    				name: 'title',
    				type: 'string'
    			}
    		]
    	});
    


    Соответственно модель UserGroup описывает структуру данных для групп пользователей, а User для самих пользователей. Сами структуры примитивные, так что останавливаться на них не буду. Далее на основании каждой модели нужно создать хранилище.

    	var userStore = Ext.create('Ext.data.Store', {
    		model: 'User',
    		autoLoad: false,
    		proxy: {
    			type: 'ajax',
    			reader: {
    				type: 'json',
    				root: 'users'
    			}
    		}
    	});
    
    	var userGroupStore = Ext.create('Ext.data.Store', {
    		model: 'UserGroup',
    		autoLoad: true,
    		proxy: {
    			type: 'ajax',
    			url: '/groups/',
    			reader: {
    				type: 'json',
    				root: 'groups'
    			}
    		}
    	});
    


    Два хранилища, используют ранее определенные модели и подгружают с сервера данные в JSON, в которых список пользователей содержится в ветке users, а список групп в ветке groups. Так же стоит обратить внимание на то, что у хранилища пользователей параметр autoLoad равен значению false. Это сделано потому что ID выбранной группы еще не определен, а скрипт возвращает список пользователей только при передаче ID группы.

    Теперь необходимо создать элементы Ext.form.ComboBox для обоих хранилищ.

    	var usersCombobox = Ext.create('Ext.form.ComboBox', {
    		fieldLabel: 'Пользователи',
    		emptyText: 'Выберите пользователя',
    		store: userStore,
    		displayField: 'login',
    		valueField: 'id'
    	});
    
    	// Create groups combobox
    	var groupsCombobox = Ext.create('Ext.form.ComboBox', {
    		fieldLabel: 'Группы',
    		emptyText: 'Выберите группу',
    		store: userGroupStore,
    		displayField: 'title',
    		valueField: 'id'
    	});
    


    Создаем два простых элемента, указываем необходимые хранилища, а так же определяем какое поле модели будет использоваться в качестве отображаемого значения, а какое в качестве значения для свойства value. После чего остается только проставить обработчик события выбора группы.

    	groupsCombobox.on('select', function () {
    		// Очищаем текущий список пользователей
    		usersCombobox.clearValue();
    
    		// Устанавливаем новый URL для хранилища пользоваталей
    		userStore.proxy.url = '/users/' + this.getValue() + '.html';
    
    		// Подгружаем новые данные в хранилище пользоваталей
    		userStore.load();
    	});
    


    Тут тоже нет ничего сложного, нужно выполнить всего три простых действия:
    1. Очистить текущий список пользователей. если ранее уже выбирали какую-то группу.
    2. На основании выбранной группы установить или сменить URL для хранилища пользоваталей.
    3. Запросить данные по обновленному URL-у хранилища.

    Ну и последним этапом размещаем элементы Ext.form.ComboBox на панели формы.

    	var searchForm = Ext.create('Ext.form.Panel', {
    		title: 'Связанные списки',
    		items: [groupsCombobox, usersCombobox],
    	});
    


    Вот в принципе и все.

    Похожие публикации

    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 3

      +1
      При возможности лучше не править свойства не описанные в документации. Иначе можно поиметь проблем при обновлении. Замену url лучше реализовать через метод, описанный в документации.
      var proxy = userStore.getProxy();
      if (proxy instanceof Ext.data.proxy.Server) {
          proxy.setUrl('/users/' + this.getValue() + '.html')
      }


      P.S. А вообще лучше всего оформить это решение через плагин, т.к. если связных комбиков будет чольше 2, то прописывать все эти зависимости друг от друга то ещё удовольствие.
        –1
        Без сомнения, навернуть функционал и улучшить метод можно, но я хотел показать самый простой способ.
        +1
        Кажется, тут лучше подошел бы Ext.data.association.Association.

        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

        Самое читаемое