ExtJS 4: Как я могу настроить магазин для загрузки моделей для определенного набора идентификаторов? - PullRequest
6 голосов
/ 21 декабря 2011

Например, скажем, у меня есть серверный API для загрузки людей, который обрабатывает запросы следующим образом: GET / people /? Id = 101,329,27

Я бы хотел создать Store (возможно, пользовательский класс, который расширяет Ext.data.Store), который - при условии, что у него есть список идентификаторов людей - заставляет прокси-сервер делать запрос, подобный показанному выше, так что возвращенные данные только для этого подмножества людей.

Я видел документацию, касающуюся удаленной фильтрации, но меня беспокоит то, что для ее использования мне сначала нужно вызвать store.load (), которая загрузит всех человек, а затем вызвать filter (), чтобы сделать удаленную фильтрация. Я хотел бы просто загрузить подмножество людей в первый раз.

Спасибо за любой совет!

Ответы [ 2 ]

5 голосов
/ 21 декабря 2011

Нашли решение (хотя все еще открыты для слушания других идей).

Сначала вы можете вызвать функцию store () магазина с объектом config, который будет передан в операцию.Документы API для Ext.data.Operation поясняют, что один из параметров конфигурации предназначен для массива объектов Filter, поэтому вы можете сделать это:

var idFilter = Ext.create('Ext.util.Filter', {
  property: 'id',
  value: '100,200,300'
});

myStore.load({
  filters: [ idFilter ]
});

Это приводит к запросу, где строка запроса URL-адресасодержит ?filter=[{"property"%3Aid%2C"value"%3A100,200,300}] (другими словами, версию [{ property: 'id', value: '100,200,300'}] в кодировке URL).

Вы также можете просто позвонить myStore.filter('id', '100,200,300'), не позвонив сначала .load().Предполагая, что у вас есть remoteFilter = true в вашем магазине, это сделает запрос с теми же параметрами запроса, показанными выше.

Sidenote : вы можете изменить ключевое слово, используемое для «фильтра», настроивПараметр конфигурации «filterParam» для прокси.Например, если filterParam = q, строка запроса, показанная выше, изменится на: ?q=[{"property"%3Aid%2C"value"%3A100,200,300}]

Секунда , вы можете управлять «структурой» фильтра в строке запроса.В моем случае я не хотел что-то вроде filter = {JSON}, как показано выше.Мне нужна строка запроса, которая выглядела так: ?id=100,200,300 Для этого мне нужно было расширить прокси и переопределить функцию getParams () по умолчанию:

Ext.define('myapp.MyRestProxy', {
    extend: 'Ext.data.proxy.Rest',

    /**
     * Override the default getParams() function inherited from Ext.data.proxy.Server.
     *
     * Note that the object returned by this function will eventually be used by
     * Ext.data.Connection.setOptions() to include these parameters via URL
     * querystring (if the request is GET) or via HTTP POST body. In either case,
     * the object will be converted into one, big, URL-encoded querystring in
     * Ext.data.Connection.setOptions() by a call to Ext.Object.toQueryString.
     * 
     * @param {Ext.data.Operation} operation
     * @return {Object}
     *  where keys are request parameter names mapped to values
     */
    getParams: function(operation) {
        // First call our parent's getParams() function to get a default array
        // of parameters (for more info see http://bit.ly/vq4OOl).
        var paramsArr = this.callParent(arguments),
            paramName,
            length;

        // If the operation has filters, we'll customize the params array before
        // returning it.
        if( operation.filters ) {
            // Delete whatever filter param the parent getParams() function made
            // so that it won't show up in the request querystring.
            delete paramsArr[this.filterParam];

            // Iterate over array of Ext.util.Filter instances and add each
            // filter name/value pair to the array of request params.
            for (var i = 0; i < operation.filters.length; i++) {
                queryParamName = operation.filters[i].property;

                // If one of the query parameter names (from the filter) conflicts
                // with an existing parameter name set by the default getParams()
                // function, throw an error; this is unacceptable and could cause
                // problems that would be hard to debug, otherwise.
                if( paramsArr[ queryParamName ] ) {
                    throw new Error('The operation already has a parameter named "'+paramName+'"');
                }

                paramsArr[ queryParamName ] = operation.filters[i].value;
            }
        }

        return paramsArr;
    }
});
1 голос
/ 22 декабря 2011

Вы также можете получить объект Model для загрузки своей записи. С контроллера вы можете сделать:

this.getRequestModel().load(requestID,{       //load from server (async)
       success: function(record, operation) {
       .....
       }
}

где Request - это класс модели, а requestID - это идентификатор для поиска. В этом сценарии объект модели тоже должен определить прокси:

proxy: {
        type: 'ajax',
        reader: {
           type:'json',
           root: 'data'
        },
        api: {
            create : 'request/create.json', //does not persist
            read   : 'request/show.json'
       }
    }
...