参照例子: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')) {
me.store is defined, just is a string.
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了。