顶级组件Account(panel)中添加了AccountGrid(gridpanel)这个子组件.
Account.js 代码:
initComponent: function() {
var me = this;
me.items = [];
me.items.push({
region : 'center',
xtype : 'accountgrid',
bind: {
title: me.title + '{selectionText}'
},
permissiveOpts: me.permissiveOpts
},{
region : 'east',
xtype : 'accountdetail',
width : 400,
title : '账号明细',
split : true,
collapsible : true,
collapsed : true,
collapseMode : 'mini'
},{
//Menu 添加、修改、查看对话框
xtype: 'accountwindow'
}
);
this.callParent(arguments);
}
AccountGrid的代码:
Ext.define('Ims.view.ckcp.widget.AccountGrid', {
extend: 'Ext.grid.Panel',
alias: 'widget.accountgrid',
requires: [
'Ims.ux.GridToolBar',
'Ext.ux.form.SearchField',
'Ims.ux.form.field.UxTreePicker',
'Ims.ux.form.trigger.TriggerClear',
'Ims.ux.iconcls.Field'
],
reference: 'accountgrid',
bind: {
store: '{accountStore}'
},
columnLines: true,
multiSelect: false,
tools: [
{
type: 'refresh',
tooltip: '刷新数据',
handler: 'refreshBtnClick'
}, {
type: 'maximize',
hidden: true,
tooltip: '隐藏记录明细',
handler: 'hideDetailBtnClick'
}, {
type: 'restore',
tooltip: '显示记录明细',
handler: 'showDetailBtnClick'
}
],
bbar:{
xtype:'pagingtoolbar',
reference:'accountgridpagingtoolbar',
bind :{
store : '{accountStore}'
},
displayInfo: true,
emptyMsg: "没有需要显示的数据",
plugins: [
Ext.create('Ext.ux.ProgressBarPager')
]
},
columns: {
items: [
{
text:'***',
searchable: true,
dataIndex:'organizationCode'
},{
text: '***',
searchable: true,
dataIndex: 'customerName'
},
{
text:'***',
searchable: true,
dataIndex: 'accountNumber'
},{
text: '***',
searchable: true,
dataIndex: 'cardNumber'
},{
text: '***',
dataIndex: 'subAccountNumber'
},{
xtype:'datecolumn',
format:'Y-m-d',
text: '***',
searchable: true,
dataIndex: 'startTime'
},{
text: '***',
xtype: 'numbercolumn',
format:'0.0000',
dataIndex: 'rate'
},{
text: '***',
dataIndex: 'productName'
},{
text: '***',
dataIndex: 'checkStatus',
renderer:function (val) {
if (val == '0') return '***';
else if(val == '1') return '登记成功';
else if(val ==2){
return '错误,请修改';
}
else if(val == '3') return '待审核';
else if(val == '4') return '***';
else if(val == '5') return '***';
else if(val == '6') return '***'
else return '***';
}
},{
text: '状态',
dataIndex: 'status',
renderer:function (val) {
if (val == '0') return '***';
else if (val=='1') return '***';
else if(val==2) return '***';
else return '***';
}
}
],
defaults: {
flex: 1
}
},
listeners:{
afterrender:function () {
var me = this,
account = me.up("ckcpaccount"),
viewModel = account.getViewModel();
if(viewModel){
var collapseBtn = me.down('buttontransparent#collapse'),
expandBtn = me.down('buttontransparent#expand');
if (collapseBtn) collapseBtn.setHidden(!viewModel.get('showGridCollapseBtn'));
if(expandBtn) expandBtn.setHidden(!viewModel.get('showGridExpandBtn'));
}
}
},
initComponent: function () {
var me = this,
searchItems=[];
var viewModel = me.up('ckcpaccount').getViewModel();
var productStoreForComboStore = viewModel.getStore('productStoreForCombo');
searchItems.push({
xtype: 'combo',
reference: 'checkStatusCombo',
fieldLabel: '状态',
displayField: 'text',
valueField: 'id',
editable: false,
name: 'queryParameter',
bind: {
store: '{checkStatusStore}',
},
value: 0,
listConfig: {
itemTpl: [
'{text}'
]
}
},{
xtype: 'combo',
name: 'productId',
fieldLabel: '***',
reference: 'productStoreForCombo',
displayField: 'name',
valueField: 'id',
scrollable: true,
autoScroll: true,
store: productStoreForComboStore
});
//表格顶部工具栏
me.dockedItems = [];
me.dockedItems.push({
xtype: 'gridtoolbar',
dock: 'top',
searchBox: true,
searchItems:searchItems,
grid: this,
permissiveOpts: me.permissiveOpts
});
console.log("accountGrid inited");
me.callParent(arguments);
}
});
AccountViewModel.js代码:
Ext.define('Ims.view.ckcp.account.AccountViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.ckcpaccount',
requires: [
'Ext.data.Store',
'Ims.model.ckcp.Rate',
'Ims.model.ckcp.Account'
],
data: {
current: {
record: null,
operation: null
},
showGridCollapseBtn: false,
showGridExpandBtn: false
},
formulas: {
accountStatus: {
bind: {
bindTo: '{current.record}',
deep: true //current.record的所有变动都会通知到menuStatus
},
get: function(record) {
var status = {
dirty: record ? record.dirty : true,
valid: record ? record.isValid() : false
};
status.validAndDirty = status.dirty && status.valid;
return status;
}
},
selectionText: {
bind: {
bindTo: '{current.record}',
deep: true
},
get: function(record) {
var title = '';
if (record) {
var path = record.data.customerName; //title 使用用户名称
title = ' 〖 ' + path + ' 〗';
}
return title;
}
},
windowOptions: {
bind: {
bindTo: '{current.operation:lowercase}',
deep: true
},
get: function(operation) {
var options = {
title: operation == 'add' ? '登记' : (operation == 'readd' ? '补登记':(operation == 'edit' ? '修改' : (operation == 'view' ? '查看账户' : ''))),
readOnly: operation == 'view' ? true : false,
saveButtonHidden: operation == 'view' ? true : false,
prevAndNextButtonHidden: operation == 'add' ? true : false
};
return options;
}
},
registeDate:{
bind:{
bindTo: '{current.operation:lowercase}',
deep: true
},
get: function (operation) {
return operation == 'readd'? null:new Date(new Date().setDate(new Date().getDate()+Ims.Config.ckcpAccountRegisterDelayDays));
}
},
currentMenu: {
bind: '{accountgrid.selection}',
get: function(account) {
this.set('current.record', account);
return account;
}
},
stores: {
organizationStore: {
type: 'tree',
model: 'Ims.model.sys.Organization',
pageSize: 0,
autoLoad: false,
remoteFilter: true,
remoteSort: true,
root: {
id: 0,
text: '最高机构',
expanded: true
}
},
checkStatusStore:{
storeId: 'checkStatusStore',
fields: ['text','id'],
data:[
['正常',0],
['已销户',1]
]
},
accountStore: {
storeId: 'accountStore', //如果store被Controller实例化,storeID会被该store的名称覆盖
pageSize: 20,
model: 'Ims.model.ckcp.Account',
autoLoad: true,
remoteFilter: true,
remoteSort: true,
listeners: {
beforeload: 'onAccountStoreBeforeLoad'
}
},
productStore:{
storeId: 'productStore',
type: 'tree',
model: 'Ims.model.ckcp.Product',
autoLoad: false,
remoteFilter: false,
remoteSort: true,
root: {
id: 0,
name: '存款产品',
expanded: true //设置为ture则无论autoload的值为多少都会autoload
},
listeners:{
load:'onProductStoreLoaded'
}
},
productStoreForCombo:{
storeId: 'productStoreForCombo',
model: 'Ims.model.ckcp.Product',
proxy: {
type: 'ajax',
url: '/ims/ckcp/product/getforcombo',
reader: {
type: 'json',
rootProperty: 'data'
}
},
remoteFilter: false,
pageSize: 0,
autoLoad: false
}
}
});
子组件可以自定义自己的ViewModel,然后在viewModel中定义自己的store。如果想使用父组件的ViewModel中的store,可以有两种方式:
(1)通过绑定,这是一种简单的方式:
bind{
store: '{productStoreForCombo}'
}
只要父组件的viewModel中定义了该productStoreForCombo即可。
来看官方文档上的一个例子:
Ext.create('Ext.panel.Panel', {
title: 'Simple Form',
viewModel: {
type: 'test'
},
layout: 'form',
defaultType: 'textfield',
items: [{
fieldLabel: 'First Name',
bind: '{firstName}' // uses "test" ViewModel from parent
},{
fieldLabel: 'Last Name',
bind: '{lastName}'
}]
});
// 绑定最有用的部分之一就是容器有的数据,子组件都可以获取。上面的例子,你可以看到,viewmodel的子组件绑定了父容器的数据。
(2)通过组件查找,直接将store赋值给组件
var viewModel = me.up('ckcpaccount').getViewModel();
var productStoreForComboStore = viewModel.getStore('productStoreForCombo');
store: productStoreForComboStore
但是这种方式需注意以下问题:
父子关系: store->combo->AccountGrid->Account
因为AccountViewModel是Account的ViewModel,所以在组件查找时必须先查找到顶级组件Account,然后通过getViewModel 可以获得AccountViewModel,然后通过ViewModel的getStore即可获得父组件中的Store。直接通过combo的getViewModel是拿不到AccountViewModel的。(记得官方文档中好像有提过子组件可以继承父组件的ViewModel,从而不需要创建自己的ViewModel)