dataview, динамическое изменение шаблона
Итак есть viewport, выводятся панели в разных регионах. К примеру, в регионе region: 'west' находится dataview и itemTpl шаблон. Все выводится все хорошо. Вопрос следующий есть ли возможность динамически менять шаблон itemTpl в dataview, к примеру при клике на какую-нибудь кнопку. Т.е. мне нужно что-бы данные выводились в одном месте с разных store с разными шаблонами. Возможно немного запутанно, но нужно направление в каком двигаться. Спасибо!
|
можно и так сделать ..только используя не вполне public api.
дело в том что так по дизайну не задумано, не преполагается в рантайме менять itemTpl. )) Традиционный вариант скорее на каждый стор имеем свой экземпляр дата вью и показываем/прячем соответствующий при клике. Но если вы сильно хотите то можно попробовать сделать и ваш сценарий. Мастер класс ковыряния в эксте :))) (на примере extjs 4.2.2): смотрим иcходники Ext.view.View в поисках itemTpl ..вхождений в коде нет ..идем далее в парента Ext.view.AbstractView ..находим обработку этого конфига в initComponent. Видим что конфиг юзается только там, при создании компонента, а далее шаблон компилируется и кладется в свойство tpl. Нам нужно делать это в рантайме ..берем кусок кода из initComponent и заворачиваем его в метод: Ext.override(Ext.view.AbstractView, { setItemTpl : function (itemTpl) { var memberFn = {}; if (Ext.isArray(itemTpl)) { // string array itemTpl = itemTpl.join(''); } else if (Ext.isObject(itemTpl)) { // tpl instance memberFn = Ext.apply(memberFn, itemTpl.initialConfig); itemTpl = itemTpl.html; } if (!this.itemSelector) { this.itemSelector = '.' + this.itemCls; } itemTpl = Ext.String.format('<tpl for="."><div class="{0}" role="{2}">{1}</div></tpl>', this.itemCls, itemTpl, this.itemAriaRole); this.tpl = new Ext.XTemplate(itemTpl, memberFn); } }); Теперь перед сменой стора надо вызывать этот метод с новым шаблоном. При смене стора должен вызваться метод refresh вашего дата вью и новые шаблоны применятся. Не проверял, но должно работать. Удачи. ;) |
вот так набросал, но есть проблема с самой store по идее, появляется лоадер и в консоль валится ошибка: Uncaught SyntaxError: Unexpected token : 80a8d5b12281c9e8ae7d88e031e83677?_dc=1413787144933 &page=1&start=0&limit=999&callback=Ext.data.JsonP :1
var panel = Ext.getCmp('dataview'); store = Ext.getStore('CarStore'); store.reload(); panel.tpl = new Ext.XTemplate('<table>', ' <tr>', ' <td width=\'200px\'><input type="checkbox" enabled="enabled" value="open" name="comment_status" <tpl if="active">checked="checked"</tpl> /><img src="http://{test}/avl_icon/get/{id}/18/any.png">{nm}</td>', ' <td class="configure"></td>', ' </tr> ', ' </table>', ' '); код самой store: Ext.define('MyApp.store.CarStore', { extend: 'Ext.data.Store', requires: [ 'MyApp.model.CarModel', 'Ext.data.JsonStore' ], constructor: function(cfg) { var me = this; cfg = cfg || {}; me.callParent([Ext.apply({ pageSize: 999, storeId: 'CarStore', model: 'MyApp.model.CarModel', proxy: { type: 'jsonp', url: 'http://localhost:3000/wialoncollector/items/'+Ext.util.Cookies.get("ssid"), actionMethods: { create: 'GET', read: 'GET', update: 'GET', destroy: 'GET' }, headers: '("Access-Control-Allow-Origin", "*")' } }, cfg)]); } }); |
видимо у тебя нет функции, которая должна вызваться. ты знаешь чем отличается json от jsonp?
|
Цитата:
|
Цитата:
объясняю. представь, у тебя есть аякс запрос и тебе сервер отдает json строку. ты ее парсишь и все ок. теперь представь, у тебя есть другой домен и ты не можешь делать кроссдоменные аякс запросы, а данные ты как то хочешь выдрать. поэтому одной из технологий для получения кроссдоменных запросов является jsonp. как она работает? ты должен понимать как эта конструкция работает: <script src="http://site.ru/js/address.js"></script> так вот, данная html конструкция тянет javascript код которой выполняется. при этом скрипт ты можешь подгружать кроссдоменно. т.е. скрипты ты можешь тянуть из любого домена, а вот аякс запросы нет. поэтому при технолгии jsonp динамически грузят какбэ скрипт, но там на деле находятся данные, обернутые в функцию или вызывается метод какого то объекта, которые это все дело парсит: callback.fun1('{param: 1}'); может я плохо объяснил, почитай в инете. но тебе главное понять суть jsonp, что это простое добавление тега <script> и указание атрибута src - пути этого скрипта. а внутри скрипта (какбы скрипта) должны быть твои данные обернутые в функцию |
вот смотри, здесь сенча дает пример, можешь посмотреть:
http://docs.sencha.com/extjs/4.2.2/e...id/paging.html а вот скрин: ![]() п.с. я надеюсь ты отладчиком умеешь пользоваться?) |
у меня url в store указан следующий:
url: 'http://localhost:3000/wialoncollector/items/'+Ext.util.Cookies.get("ssid") Ext.util.Cookies.get("ssid") - сессия которую я получаю только после успешного прохождения формы логина, поэтому не понятно как подключить в index.html мой скрипт по типу: <script src="http://domainB.com/users?callback=someCallback"></script> Возможно мне и нет необходимости использовать jsonp, указал просто в store type: 'ajax' , выполняю код что выше указывал: var panel = Ext.getCmp('dataview'); store = Ext.getStore('CarStore'); store.reload(); panel.tpl = new Ext.XTemplate('<table>', ' <tr>', ' <td width=\'200px\'><input type="checkbox" enabled="enabled" value="open" name="comment_status" <tpl if="active">checked="checked"</tpl> /><img src="http://{test}/avl_icon/get/{id}/18/any.png">{nm}</td>', ' <td class="configure"></td>', ' </tr> ', ' </table>', ' '); Но в консоль валится ошибка: XMLHttpRequest cannot load [url]http://localhost:3000/wialoncollector/items/fb3c15cf898d432044321014e3d1c017?_dc=1413798123228&page=1&start=0&limit=999[/url]. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access. Если перехожу по урлу просто http://localhost:3000/wialoncollecto...rt=0&limit=999 json вижу. А вообще задача изначально следующая есть выпадающий список, нужно подгружать данные с разных store в dataview со своими шаблонами. Как бы с подключением шаблона вроде разобрались. Теперь я правильно понимаю команда: store.reload(); дергает store, она в свою очередь шлет запрос, который указан в proxy, данные автоматом парсятся и заносятся в dataview? Вот с последним проблемы... |
вы читали, что я вам писал?
1) No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access. это означает, что нельзя делать кроссдоменный запрос. 2) вам надо писать не ajax а jsonp: type: 'jsonp' еще раз даю ссылку на пример: http://docs.sencha.com/extjs/4.2.2/e...id/paging.html вот он код: http://docs.sencha.com/extjs/4.2.2/e...grid/paging.js как описывается стора: var store = Ext.create('Ext.data.Store', { pageSize: 50, model: 'ForumThread', remoteSort: true, proxy: { // load using script tags for cross domain, if the data in on the same domain as // this page, an HttpProxy would be better type: 'jsonp', url: 'http://www.sencha.com/forum/topics-browse-remote.php', reader: { root: 'topics', totalProperty: 'totalCount' }, // sends single sort as multi parameter simpleSortMode: true }, sorters: [{ property: 'lastpost', direction: 'DESC' }] }); вот то что приходит с сервера: http://www.sencha.com/forum/topics-b...nP .callback2 |
Ок, по первому понятно. По второму, вот читаю документацию http://docs-origin.sencha.com/extjs/...ta.proxy.JsonP , согласно которой я должен указать в store callbackKey: 'theCallbackFunction', я это сделал. Далее я должен подключить скрипт url которого прописан в store, в моем случае: url: 'http://localhost:3000/wialoncollector/items/'+Ext.util.Cookies.get("ssid"). Согласно той же документации я должен подключить скрипт в index.html типа: <script src="http://localhost:3000/wialoncollector/items/'+Ext.util.Cookies.get("ssid")?callback=theCallbac kFunction"></script>. Теперь что из этого не верно, если все верно, как я могу подключить скрипт в котором используется сессия: Ext.util.Cookies.get("ssid") которую я получаю только после успешного прохода формы логина?
Примеры посмотрел, все вроде понятно, но у себя пока не получается реализовать, также не вижу в примерах callback функции. |
я так понял, что я буду вам 3 года объяснять. основу взял отсюда:
http://docs.sencha.com/extjs/4.2.2/e...tml?theme=gray вы в проксе пишите тип jsonp, указывайте урлу и далее нужные вам параметры. тэг script extjs создаст самостоятельно, это для вас скрыто, т.к. оно вам не нужно. если вы посмотрите в нетворке список передаваемых параметров, то увидите вот такой список: _dc:1413807788180 page:1 start:0 limit:50 callback:Ext.data.JsonP.callback1 где: _dc - параметр с рандомным значением (очистка кеша) page, start, limit - задает правило как нужно выводить данные. с какой по какой записи. т.е. с 0 по 50 записи (или 1 ая страница) callback - это как раз функция, которая должна вызываться после того как скрипт подгрузится. т.е. вы должы свои данные обернуть в эту функцию: Ext.data.JsonP.callback1({... ваши данные...}); причем каждый раз имя функции меняется!!! вот пример, вырезав все нахрен из того примера: <html> <head> <!--<link href="ext-4.2.1.883/resources/ext-theme-gray/ext-theme-gray-all-debug.css" rel="stylesheet"/> <script src="ext-4.2.1.883/ext-all.js"></script>--> <link href="http://docs.sencha.com/extjs/4.2.2/extjs-build/resources/css/ext-all-gray-debug.css" rel="stylesheet"/> <script src="http://docs.sencha.com/extjs/4.2.2/extjs-build/ext-all.js"></script> <script> Ext.onReady(function () { var store = Ext.create('Ext.data.Store', { pageSize: 50, fields: ['title'], proxy: { type: 'jsonp', url: 'http://www.sencha.com/forum/topics-browse-remote.php', reader: { root: 'topics', totalProperty: 'totalCount' } }, autoLoad: true }); var grid = Ext.create('Ext.grid.Panel', { width: 400, height: 300, title: 'Browse Forums', store: store, // grid columns columns:[{ text: "Topic", dataIndex: 'title', flex: 1, sortable: false }], renderTo: Ext.getBody() }); }); </script> </head> <body></body> </html> |
Цитата:
|
Разобрался, оказывается у меня запрос отправлялся локально на сервер по localhost, оказывается ему это не нравится, пришлось домен прописать и все заработало. Спасибо, skrudjmakdak
Данные то вывелись все ок, но данные как-то одним блоком, т.е. не так как в dataview, теперь не могу применить onDataviewSelect к данным. Т.е. где-то затерялся в DOM div с class="x-dataview-item x-item-selected" |
если еще не разобрались с этой проблемой, то показывайте свой код, я не экстрасенс
|
Цитата:
items: [ { xtype: 'dataview', autoScroll: true, id: 'dataview', margin: '10 0 10 10', disableSelection: false, itemSelector: 'div', itemTpl: [ '<table>', ' <tr>', ' <td width=\'200px\'><input type="checkbox" enabled="enabled" value="open" name="comment_status" <tpl if="active">checked="checked"</tpl> /><img src="{host}/avl_icon/get/{id}/18/any.png">{nm}</td>', ' <td class="configure"></td>', ' </tr> ', ' </table>', ' ' ], store: 'CarStore', listeners: { itemclick: { fn: 'onDataviewSelectConfigure', single: false }, select: 'onDataviewSelect' } } Далее у меня выпадающий список, я перехожу по нему подгрузились другие данные, далее переходу опять чтобы вернуть это же: onObjectsClick: function(component, eOpts) { var panel = Ext.getCmp('dataview'); store = Ext.getStore('CarStore'); store.reload(); panel.tpl = new Ext.XTemplate( '<tpl for=".">', '<table class="tabview">', ' <tr>', ' <td width=\'200px\'><input type="checkbox" enabled="enabled" value="open" name="comment_status" <tpl if="active">checked="checked"</tpl> /><img src="{host}/avl_icon/get/{id}/18/any.png">{nm}</td>', ' <td class="configure"></td>', ' </tr> ', ' </table>', '</tpl>', ' '); } Мой код store: Ext.define('MyApp.store.CarStore', { extend: 'Ext.data.Store', requires: [ 'MyApp.model.CarModel', 'Ext.data.JsonStore', 'Ext.data.proxy.Ajax', 'Ext.data.JsonPStore' ], constructor: function(cfg) { var me = this; cfg = cfg || {}; me.callParent([Ext.apply({ pageSize: 999, storeId: 'CarStore', model: 'MyApp.model.CarModel', proxy: { type: 'jsonp', url: 'http://{host}/ajax.html?svc=core/search_items¶ms={spec:{itemsType:avl_unit,propName:sys_unique_id,' + 'propValueMask:*,sortType:sys_name,propType:list},force:1,flags:0xffffffff,from:0,to:0xffffffff}' + '&ssid='+Ext.util.Cookies.get("ssid"), callbackKey: 'callback', reader: { root: 'items' }, headers: '("Access-Control-Allow-Origin", "*")' } }, cfg)]); } }); Данные подгрузились также но метод выбора select: 'onDataviewSelect' не доступен. Вопрос как теперь опять повесить event на DataviewSelect? Если не понятно, могу приложить скрины |
что значит не доступен? он вообще не отрабатывает? или может иллюзия того что не отрабатывает?
попробуте передать функцию: select: function () {console.log('меня выбрали');} и если можно, то киньте скрины |
Вложений: 2
Цитата:
Первый скрин видно что есть div и есть возможность выбора строки, http://s020.radikal.ru/i711/1410/14/12b41390b1b1.png второй скрин нету div и при клике ничего не проиходит http://s017.radikal.ru/i407/1410/1e/15a856722b33.png |
Во view в type: dataview у меня стоит select: 'onDataviewSelect', после выполнения функции onObjectsClick, у меня должно все также отрабатывать select: 'onDataviewSelect' или нужно вешать как то по новому event?
|
Есть какие-то идеи чтобы после использования смены шаблона в dataview: new Ext.XTemplate оставались рабочими events, к примеру click. Возможно по структуре что-то не так?
|
Часовой пояс GMT +3, время: 07:15. |