參照例子:http://www.mhzg.net/a/20115/20115311100255.html 學習Extjs MVC模式。遇到了一個EXTJS 4 MVC模式VIEW中searchfield指定store無效的問題。
app.js
Ext.Loader.setConfig({enabled: true});Ext.Loader.setPath('Ext.ux', 'extjs/ux');Ext.require([ 'Ext.grid.*', 'Ext.toolbar.Paging', 'Ext.util.*', 'Ext.data.*', 'Ext.panel.Panel', 'Ext.view.View', 'Ext.layout.container.Fit', 'Ext.ux.form.SearchField']);
view中的定義
Ext.define('BJXC.view.PhoneBrand.List' ,{ extend: 'Ext.grid.Panel', alias : 'widget.PhoneBrandList', //別名為userlist id : 'PhoneBrandListGrid', title : '手機品牌', iconCls: 'icon-user', store: 'PhoneBrand', columnLines: true, columns: [ {header: '序號', dataIndex: 'id', width: 40}, {header: '中文簡稱', dataIndex: 'ZWM', flex: 1}, {header: '英文名稱', dataIndex: 'YWM', flex: 1}, {header: '中文全稱', dataIndex: 'ZWQC', flex: 1}, {header: '網站', dataIndex: 'KFWZ', flex: 1}, {header: '客服電話', dataIndex: 'KFDH', flex: 1}, {header: '客服地址', dataIndex: 'KFDZ', flex: 1} ], viewConfig: { stripeRows: true, //顯示斑馬線 enableTextSelection: true //啟用文字選擇 }, dockedItems: [{ dock: 'top', xtype: 'toolbar', items: [{ iconCls: 'icon-add', text: '添加', action:'add', scope: this }, { iconCls: 'icon-delete', text: '刪除', action:'delete', scope: this },'-',{ xtype: 'searchfield', width: 300, fieldLabel: '搜尋', labelWidth: 50, store: 'PhoneBrand' }] },{ dock: 'bottom', xtype: 'pagingtoolbar', store: 'PhoneBrand', displayInfo: true, pageSize: 10, emptyMsg: '沒有記錄' }]});
執行的時候,錯誤如下:
TypeError: me.store.proxy is undefined[在此錯誤處中斷] if (!me.store.proxy.hasOwnProperty('filterParam')) {
搜尋資料,得以下網址:http://www.sencha.com/forum/showthread.php?208604-ERROR-with-SearchField-and-the-error-is-me.store.proxy-is-undefined
me.store is defined, just is a string.
http://www.sencha.com/forum/showthread.php?131842-4.0.0-MVC-Grid-store-problems-grouping-and-searchfield
the same problem, grouping feature doesn't work when we respect the MVC pattern. If the store is defined as a var then works.
也就是說,在VIEW中指定的store: 'PhoneBrand',其實只是一個字串,並沒不是變數。而上面的例子中,store是一個建立了的變數。
開啟\extjs\ux\form\SearchField.js,在大概22行處,增加以下代碼,patch一下吧
if(typeof(me.store.isStore) == 'undefined') { me.store = Ext.data.StoreManager.get(me.store); }
同時,在store的代碼中,也要指定storeId,如storeId:'PhoneBrand',
完整的Ext.ux.form.SearchField的代碼如下,Extjs 4.1.1a版本。
Ext.define('Ext.ux.form.SearchField', { extend: 'Ext.form.field.Trigger', alias: 'widget.searchfield', trigger1Cls: Ext.baseCSSPrefix + 'form-clear-trigger', trigger2Cls: Ext.baseCSSPrefix + 'form-search-trigger', hasSearch : false, paramName : 'query', initComponent: function() { var me = this; me.callParent(arguments); me.on('specialkey', function(f, e){ if (e.getKey() == e.ENTER) { me.onTrigger2Click(); } }); // console.log(me.store); // console.log(me.store.isStore); if(typeof(me.store.isStore) == 'undefined') { me.store = Ext.data.StoreManager.get(me.store); } // We're going to use filtering me.store.remoteFilter = true; // Set up the proxy to encode the filter in the simplest way as a name/value pair // If the Store has not been *configured* with a filterParam property, then use our filter parameter name if (!me.store.proxy.hasOwnProperty('filterParam')) { me.store.proxy.filterParam = me.paramName; } me.store.proxy.encodeFilters = function(filters) { return filters[0].value; } }, afterRender: function(){ this.callParent(); this.triggerCell.item(0).setDisplayed(false); }, onTrigger1Click : function(){ var me = this; if (me.hasSearch) { me.setValue(''); me.store.clearFilter(); me.hasSearch = false; me.triggerCell.item(0).setDisplayed(false); me.updateLayout(); } }, onTrigger2Click : function(){ var me = this, value = me.getValue(); if (value.length > 0) { // Param name is ignored here since we use custom encoding in the proxy. // id is used by the Store to replace any previous filter me.store.filter({ id: me.paramName, property: me.paramName, value: value }); me.hasSearch = true; me.triggerCell.item(0).setDisplayed(true); me.updateLayout(); } }});
改了一下SearchField.js ,就可以直接在View中指定store了。