- Ext.grid.CheckboxSelectionModel = Ext.extend(Ext.grid.RowSelectionModel, {
- …
- initEvents : function(){
- Ext.grid.CheckboxSelectionModel.superclass.initEvents.call(this);
- this.grid.on('render', function(){
- var view = this.grid.getView();
- view.mainBody.on('mousedown', this.onMouseDown, this);
- Ext.fly(view.innerHd).on('mousedown', this.onHdMouseDown, this);
-
- }, this);
- },
-
-
- onMouseDown : function(e, t){
- if(e.button === 0 && t.className == 'x-grid3-row-checker'){
- e.stopEvent();
- var row = e.getTarget('.x-grid3-row');
- if(row){
- var index = row.rowIndex;
- if(this.isSelected(index)){
- this.deselectRow(index);
- }else{
- this.selectRow(index, true);
- }
- }
- }
- },
-
-
- onHdMouseDown : function(e, t){
- if(t.className == 'x-grid3-hd-checker'){
- e.stopEvent();
- var hd = Ext.fly(t.parentNode);
- var isChecked = hd.hasClass('x-grid3-hd-checker-on');
- if(isChecked){
- hd.removeClass('x-grid3-hd-checker-on');
- this.clearSelections();
- }else{
- hd.addClass('x-grid3-hd-checker-on');
- this.selectAll();
- }
- }
- },
- …
- });
Ext.grid.CheckboxSelectionModel = Ext.extend(Ext.grid.RowSelectionModel, {
…
initEvents : function(){
Ext.grid.CheckboxSelectionModel.superclass.initEvents.call(this);
this.grid.on('render', function(){
var view = this.grid.getView();
view.mainBody.on('mousedown', this.onMouseDown, this);
Ext.fly(view.innerHd).on('mousedown', this.onHdMouseDown, this);
}, this);
},
// private
onMouseDown : function(e, t){
if(e.button === 0 && t.className == 'x-grid3-row-checker'){ // Only fire if left-click
e.stopEvent();
var row = e.getTarget('.x-grid3-row');
if(row){
var index = row.rowIndex;
if(this.isSelected(index)){
this.deselectRow(index);
}else{
this.selectRow(index, true);
}
}
}
},
// private
onHdMouseDown : function(e, t){
if(t.className == 'x-grid3-hd-checker'){
e.stopEvent();
var hd = Ext.fly(t.parentNode);
var isChecked = hd.hasClass('x-grid3-hd-checker-on');
if(isChecked){
hd.removeClass('x-grid3-hd-checker-on');
this.clearSelections();
}else{
hd.addClass('x-grid3-hd-checker-on');
this.selectAll();
}
}
},
…
});
但是我们又不希望修改EXT的源代码,后来就想到可以扩展CheckboxSelectionModel这个类。实现如下:
ExtCheckboxSelectionModel.js
- Ext.grid.ExtCheckboxSelectionModel = Ext.extend(Ext.grid.CheckboxSelectionModel, {
- hd : null,
- onHdMouseDown : function(e, t){
- Ext.grid.ExtCheckboxSelectionModel.superclass.onHdMouseDown.call(this, e, t);
-
- if (this.hd == null && t.className == 'x-grid3-hd-checker') {
- this.hd = t.parentNode;
-
- this.on('rowdeselect', this.offHdChecker, this);
- }
- },
- offHdChecker : function() {
- if (this.hd == null)
- return;
-
- var hd = Ext.fly(this.hd);
- var isChecked = hd.hasClass('x-grid3-hd-checker-on');
- if(isChecked)
- hd.removeClass('x-grid3-hd-checker-on');
- }
- });
Ext.grid.ExtCheckboxSelectionModel = Ext.extend(Ext.grid.CheckboxSelectionModel, {
hd : null,
onHdMouseDown : function(e, t){
Ext.grid.ExtCheckboxSelectionModel.superclass.onHdMouseDown.call(this, e, t);
if (this.hd == null && t.className == 'x-grid3-hd-checker') {
this.hd = t.parentNode;
this.on('rowdeselect', this.offHdChecker, this);
}
},
offHdChecker : function() {
if (this.hd == null)
return;
var hd = Ext.fly(this.hd);
var isChecked = hd.hasClass('x-grid3-hd-checker-on');
if(isChecked)
hd.removeClass('x-grid3-hd-checker-on');
}
});
在这个扩展类中,我们继承了基类的onHdMouseDown方法(虽然Ext已经把这个类声明成私有变量,并且也不希望用户重写,但是在有些情况下我们也只能通过Ext不推荐的方式来实现了),这个方法是在用户点击标题栏的全选复选框时执行,我们先维护一个hd属性,这个属性存放标题栏的全选复选框的父节点,扩展方法onHdMouseDown先执行父类的onHdMouseDown方法,然后检查是否已经设置了hd属性的值,如果没有设置,则设置hd属性的值为标题栏的全选复选框的父节点,并且添加rowdeselect事件(行取消选中)的处理函数。
在rowdeselect事件处理函数中,首先检查是否设置类hd属性,如果设置了hd属性,表示标题栏的全选复选框曾经点击过,然后判断全选复选框是否为选中状态,如果是,则设置全选复选框是否为非选中状态。
在使用时,我们只要把原来new Ext.grid.CheckboxSelectionModel()的地方改成new Ext.grid.ExtCheckboxSelectionModel()即可实现客户要求的功能。
在使用过程中,发现已经有很多地方用了new Ext.grid.CheckboxSelectionModel(),我们不希望每个地方都要修改一次,工作量太大,还可能有遗漏,我们希望有个地方修改一下,就可以实现所有的地方都调整,但是又不希望修改源代码,通过查资料,想到了一种办法:
ext-extends.js
- if (Ext.grid.CheckboxSelectionModel) {
- var interceptOnHdMouseDown = Ext.grid.CheckboxSelectionModel.prototype.onHdMouseDown.createInterceptor(function(e, t){
- if (this.hd == null && t.className == 'x-grid3-hd-checker') {
- this.hd = t.parentNode;
-
- this.on('rowdeselect', this.offHdChecker, this);
- }
- });
-
- Ext.override(Ext.grid.CheckboxSelectionModel, {
- hd : null,
- onHdMouseDown : interceptOnHdMouseDown,
- offHdChecker : function() {
- if (this.hd == null)
- return;
-
- var hd = Ext.fly(this.hd);
- var isChecked = hd.hasClass('x-grid3-hd-checker-on');
- if(isChecked)
- hd.removeClass('x-grid3-hd-checker-on');
- }
- });
- }
if (Ext.grid.CheckboxSelectionModel) {
var interceptOnHdMouseDown = Ext.grid.CheckboxSelectionModel.prototype.onHdMouseDown.createInterceptor(function(e, t){
if (this.hd == null && t.className == 'x-grid3-hd-checker') {
this.hd = t.parentNode;
this.on('rowdeselect', this.offHdChecker, this);
}
});
Ext.override(Ext.grid.CheckboxSelectionModel, {
hd : null,
onHdMouseDown : interceptOnHdMouseDown,
offHdChecker : function() {
if (this.hd == null)
return;
var hd = Ext.fly(this.hd);
var isChecked = hd.hasClass('x-grid3-hd-checker-on');
if(isChecked)
hd.removeClass('x-grid3-hd-checker-on');
}
});
}
在上面的实现方法中,先判断当前是否有Ext.grid.CheckboxSelectionModel的定义(有可能我们通过定制js,没有使用这个功能),然后创建针对CheckboxSelectionModel的onHdMouseDown方法的拦截器函数,这个函数会在执行CheckboxSelectionModel的onHdMouseDown方法以前执行我们自己的拦截方法,拦截方法的检查是否已经设置了hd属性的值,如果没有设置,则设置hd属性的值为标题栏的全选复选框的父节点,并且添加rowdeselect事件(行取消选中)的处理函数。
然后我们通过调用Ext.override函数给Ext.grid.CheckboxSelectionModel类添加hd属性和offHdChecker方法,并用拦截器函数替换原有的onHdMouseDown方法,使用时,在加载了ext-all.js后,再加载ext-extends.js,由此,实现了在不修改源代码的情况下,修改Ext.grid.CheckboxSelectionModel类功能的机制
在这里的关键是:通过生成一个原有类方法的拦截器方法,并重载这个方法,可以实现在不修改源代码、以及不生成扩展类的情况下,扩展原有类的方法和功能。