容器层次结构中的模态窗口是不好的模式?

时间:2011-08-07 17:56:10

标签: design-patterns extjs modal-dialog

extjs webapp。

我们有一个复杂的全屏布局,它有一个表单。表单有一个自定义字段组件,它启动一个窗口,窗口有另外需要发布的表单字段,所以我们将窗口作为父窗口,使得他是表单面板的后代。当我们设置modal:true时,我们在窗口所拥有的面板上得到一个模态掩码(好)但是模态掩码的大小错误,导致窗体上的滚动条不合适。

如果你看一下模态窗口的掩码实现[1],很明显模态窗口不是为了掩盖整个页面以外的任何东西。我通常同意Extjs的实现细节,这让我想知道子面板中的模态窗口是否存在设计或可用性方面的挑战,我不相信?

[1] http://www.sencha.com/forum/showthread.php?141901-are-modal-windows-inside-a-container-a-bad-idea&p=630526#post630526

1 个答案:

答案 0 :(得分:0)

如果有人在这里搜索,我们继续攻击并支持模态窗口,这很容易,我不会预见到问题。

// developed and tested against Ext 3.3.3
djg.ContainedModalWindow = Ext.extend(Ext.Window, {

    // *djg* new method
    sizeMask: function() {
        if (this.ownerCt) {
            // mind was blown at first, but no-op here works.
            // it looks like the dom gets sized just fine automatically
            // if there is a container hierarchy with a layout.
            // we just have to prevent Ext from overriding it below.
        }
        else {
            // normal Ext 3.3.3 behavior
            this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
        }
    },

    // private
    beforeShow : function(){
        delete this.el.lastXY;
        delete this.el.lastLT;
        if(this.x === undefined || this.y === undefined){
            var xy = this.el.getAlignToXY(this.container, 'c-c');
            var pos = this.el.translatePoints(xy[0], xy[1]);
            this.x = this.x === undefined? pos.left : this.x;
            this.y = this.y === undefined? pos.top : this.y;
        }
        this.el.setLeftTop(this.x, this.y);


        if(this.expandOnShow){
            this.expand(false);
        }


        if(this.modal){
            Ext.getBody().addClass('x-body-masked');
            this.sizeMask(); // *djg*
            this.mask.show();
        }
    },

    // private
    onWindowResize : function(){
        if(this.maximized){
            this.fitContainer();
        }
        if(this.modal){
            // begin *djg*
            //this.mask.setSize('100%', '100%');
            //var force = this.mask.dom.offsetHeight;
            //this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
            this.sizeMask(); 
            // end *djg*
        }
        this.doConstrain();
    }
});