原文地址 http://blog.csdn.net/jaune161/article/details/18266301 转载请注明出处
实现的基本思想就是为form绑定一个store,然后监听store的load事件,先上代码然后我一步一步讲思路。
代码有点多,但是重点就只有几个方法,为了让大家理解的更深,所以引入了一点源码,可以直接略过前面的代码,看后面的部分,然后再看前面的代码,以了解整体的实现思路。
Ext.define('Xzr.view.security.role.authority.RoleAuthority',{
extend:'Ext.form.Panel',
requires:['Xzr.ux.form.AuthorityFieldSet'],
mixins: {
bindable: 'Ext.util.Bindable'
},
alias:'widget.roleauthority',
url:'security/role/save/authorities',
region:'center',
title:'角色权限分配',
autoDestroy:true,
width:700,
bodyPadding:10,
border:false,
overflowY:'auto',
layout: {
type:'vbox',
align:'stretch'
},
loadmask:'正在加载系统权限信息',
buttonAlign:'center',
store:'security.AuthoritiesByRoleStore',
initComponent:function(){
var me = this;
me.store = Ext.data.StoreManager.lookup(me.store || 'ext-empty-store');
me.buttons=[
{text:'确定',action:'ok'},
{text:'重置',action:'reset'}
];
me.items = [
{xtype:'hiddenfield',name:'roleId'},
{
xtype: 'checkboxgroup',
itemId:'checkboxgroup-container',
layout: {
type:'vbox',
align:'stretch'
}
}
]
me.bindStore(me.store,true),
me.callParent();
},
onRender:function(){
var me = this;
if(Ext.isString(me.loadmask)){
me.loadmask = new Ext.LoadMask(me, {msg:me.loadmask});
}
me.loadmask.bindStore(me.store);
this.callParent(arguments);
},
getStoreListeners: function() {
return {
load: this.onLoad
};
},
onLoad:function(store, records, successful, eOpts){
var me = this,
container = me.getCheckboxContainer();
container.removeAll();
store.each(function(record){
me.createCheckbox(record);
});
},
createCheckbox:function(record){
var me = this,
boxLabel = record.get('authorityName')+'('+record.get('authorityMark')+')',
value = record.getId(),
moduleId = record.get('moduleId')||'others',
remark = record.get('remark')||'全局权限'
var fieldSet = me.createFeildSet(moduleId,remark);
fieldSet.add({
xtype:'checkbox',
itemId:value,
boxLabel:boxLabel,
inputValue:value,
submitValue:value,
name:'sysAuthorities'
});
},
createFeildSet:function(itemId,title){
var me = this,
container = me.getCheckboxContainer(),
fieldset = container.down('#'+itemId);
if(!fieldset){
fieldset = container.add({
xtype:'authorityfieldset',
title:title,
itemId:itemId
});
}
return fieldset;
},
getCheckboxContainer:function(){
return this.down('#checkboxgroup-container');
}
onDestroy:function(){
this.loadmask.destroy();
this.callParent(arguments);
}
});
先讲实现动态checkbox
首先要实现store绑定需要在form中添加下面的代码
mixins: {
bindable: 'Ext.util.Bindable'
},
这是Ext提供的一个供绑定store的一个工具类,在mixins中添加这个类之后就可以直接调用bingStore、getStore方法了,现在直接贴上Ext.util.Bindable的源代码方便下面讲解
/**
* This class is used as a mixin.
*
* This class is to be used to provide basic methods for binding/unbinding stores to other
* classes. In general it will not be used directly.
*/
Ext.define('Ext.util.Bindable', {
/**
* Binds a store to this instance.
* @param {Ext.data.AbstractStore/String} [store] The store to bind or ID of the store.
* When no store given (or when `null` or `undefined` passed), unbinds the existing store.
*/
bindStore: function(store, initial, propertyName) {
// Private params
// @param {Boolean} [initial=false] True to not remove listeners from existing store.
// @param {String} [propertyName="store"] The property in this object under which to cache the passed Store.
propertyName = propertyName || 'store';
var me = this,
oldStore = me[propertyName];
if (!initial && oldStore) {
// Perform implementation-specific unbinding operations *before* possible Store destruction.
me.onUnbindStore(oldStore, initial, propertyName);
if (store !== oldStore && oldStore.autoDestroy) {
oldStore.destroyStore();
} else {
me.unbindStoreListeners(oldStore);
}
}
if (store) {
store = Ext.data.StoreManager.lookup(store);
me.bindStoreListeners(store);
me.onBindStore(store, initial, propertyName);
}
me[propertyName] = store || null;
return me;
},
/**
* Gets the current store instance.
* @return {Ext.data.AbstractStore} The store, null if one does not exist.
*/
getStore: function(){
return this.store;
},
/**
* Unbinds listeners from this component to the store. By default it will remove
* anything bound by the bindStoreListeners method, however it can be overridden
* in a subclass to provide any more complicated handling.
* @protected
* @param {Ext.data.AbstractStore} store The store to unbind from
*/
unbindStoreListeners: function(store) {
// Can be overridden in the subclass for more complex removal
var listeners = this.storeListeners;
if (listeners) {
store.un(listeners);
}
},
/**
* Binds listeners for this component to the store. By default it will add
* anything bound by the getStoreListeners method, however it can be overridden
* in a subclass to provide any more complicated handling.
* @protected
* @param {Ext.data.AbstractStore} store The store to bind to
*/
bindStoreListeners: function(store) {
// Can be overridden in the subclass for more complex binding
var me = this,
listeners = Ext.apply({}, me.getStoreListeners(store));
if (!listeners.scope) {
listeners.scope = me;
}
me.storeListeners = listeners;
store.on(listeners);
},
/**
* Gets the listeners to bind to a new store.
* @protected
* @param {Ext.data.Store} store The Store which is being bound to for which a listeners object should be returned.
* @return {Object} The listeners to be bound to the store in object literal form. The scope
* may be omitted, it is assumed to be the current instance.
*/
getStoreListeners: Ext.emptyFn,
/**
* Template method, it is called when an existing store is unbound
* from the current instance.
* @protected
* @param {Ext.data.AbstractStore} store The store being unbound
* @param {Boolean} initial True if this store is being bound as initialization of the instance.
*/
onUnbindStore: Ext.emptyFn,
/**
* Template method, it is called when a new store is bound
* to the current instance.
* @protected
* @param {Ext.data.AbstractStore} store The store being bound
* @param {Boolean} initial True if this store is being bound as initialization of the instance.
*/
onBindStore: Ext.emptyFn
});
看bindStore方法中调用了bindStoreListeners方法,这个方法是为store绑定事件的,而bindStoreListeners中调用了getStoreListeners方法,这个方法是获取要绑定的事件的方法,我们可以直接在定义的form中写这个方法来达到绑定事件的效果,如下代码
getStoreListeners: function() {
return {
load: this.onLoad
};
},
onLoad:function(store, records, successful, eOpts){
var me = this,
container = me.getCheckboxContainer();
container.removeAll();
store.each(function(record){
me.createCheckbox(record);
});
},
这段代码的意思就是为Store的load方法绑定load事件,然后在onLoad方法中执行创建checkbox的过程,这个就简单了,无非就是先把容器中的checkbox移除掉,然后再遍历Store根据后台返回的数据一个一个将checkbox添加到容器中。
下面说一下绑定loadMask
我form中定义的loadMask属性仅仅是定义了提示内容,其实可以定义成一个对象,这样可以支持更多的配置项,不过跟我的这个原理是一样的
需要做的第一步是重写onRender方法,然后在这个方法里创建loadMask对象
onRender:function(){
var me = this;
if(Ext.isString(me.loadmask)){
me.loadmask = new Ext.LoadMask(me, {msg:me.loadmask});
}
me.loadmask.bindStore(me.store);
this.callParent(arguments);
},
new Ext.LoadMask(me, {msg:me.loadmask});第一个参数是要遮罩的对象,也就是form,第二个参数是配置项
loadMask的创建必须在onRender方法中,而不能在initComponent方法中,因为在initComponent方法中form还没有创建出来如果这时候将form跟loadmask绑定的话会报错。
me.loadmask.bindStore(me.store);是为loadmask指定要绑定的Store,指定Store后,在Store加载时loadmask会自动显示,而在加载结束后loadmask会自动隐藏
注意最后的这段代码
onDestroy:function(){
this.loadmask.destroy();
this.callParent(arguments);
}
需要在form销毁的时候同时将loadmask也销毁,否则会造成资源的浪费
效果展示,在加载是弹出loadmask提示信息
加载完后的效果