Javascript 基于插件的GUI中的模型视图演示者生命周期管理

Javascript 基于插件的GUI中的模型视图演示者生命周期管理,javascript,language-agnostic,plugins,mvp,Javascript,Language Agnostic,Plugins,Mvp,当GUI由多个子组件组成时,我将它们视为具有自己的演示者和模型的独立视图,是否有一种将它们粘合在一起的模式?一些子组件会持续出现在屏幕上,而其他子组件则会在屏幕上交换 对于在运行时添加到GUI的子组件,实例化相应的MVP三元组,什么样的工厂模式是好的 如何将子组件与GUI的持久“容器”部分以及彼此粘合在一起?是否会有一个“上帝演讲者”将其他演讲者联系在一起 更新:我现在正在寻找类似Eclipse扩展机制的东西。插件将自己注册到全局注册表,以获得它们提供的功能。当需要返回数据或呈现视图等功能时,将

当GUI由多个子组件组成时,我将它们视为具有自己的演示者和模型的独立视图,是否有一种将它们粘合在一起的模式?一些子组件会持续出现在屏幕上,而其他子组件则会在屏幕上交换

  • 对于在运行时添加到GUI的子组件,实例化相应的MVP三元组,什么样的工厂模式是好的
  • 如何将子组件与GUI的持久“容器”部分以及彼此粘合在一起?是否会有一个“上帝演讲者”将其他演讲者联系在一起
  • 更新:我现在正在寻找类似Eclipse扩展机制的东西。插件将自己注册到全局注册表,以获得它们提供的功能。当需要返回数据或呈现视图等功能时,将查询注册表并调用返回的函数(这是纯JavaScript,因此我不使用接口)。我将使用纯插件方法,其中所有内容(甚至主视图)都是插件。我还可以使用事件总线让不同的演示者以不可知论的方式进行交流

    现在,我更具体的问题是,当插件将要提供一个视图时,我应该如何初始化MVP空间坐标轴并将视图渲染到父容器中(模块外部)。我可能需要让视图自己呈现到从外部传递的容器中,并将视图和模型(如果需要)注入到演示器中。另一种方法是视图返回一个可以放置在容器中的组件,但这与我的设想背道而驰,即将所有特定于GUI框架的内容都保存在视图实现中。我更喜欢工厂/胶水机制是否是框架无关的


    好的,我现在就停止唠叨,等待一些反馈,然后也许会补充更多关于我到底被困在哪里的澄清…

    现在,我采用这种方法:

    贡献GUI组件的扩展器(插件公开的扩展实现)有一个
    getTriad
    (稍后将给出更好的名称)方法,该方法实例化、连接并返回MVP三元组。视图有一个
    getComponent
    方法,该方法呈现并返回一个特定于框架的GUI元素容器,该容器可以添加到父容器中(特定于框架的详细信息封装在父视图中)。我不是让视图将自身渲染到容器中,而是让父视图将子视图渲染到自身中。我认为这在确保子视图不会直接干扰父视图方面更好。

    我想“保持特定于GUI框架的内部视图实现”是整个应用程序级设计的选择,而不是绝对必须的(至少当您认为“视图实现”是“插件视图实现”时)

    例如,您可以在插件级别有一个非常薄的视图层,并在父级中实现一个调用插件的超级视图层:考虑到一个插件系统,所有插件都向表中添加了一列,您很可能在父级(“表”)拥有大部分视图代码让你的插件只传递一点点原始数据:你将避免重复自己的工作,并使你的代码更加灵活和可维护

    另一方面,如果您的插件提供了非常不同类型的功能,而这些功能从未直接交互(例如,如果它们是飞行模拟器的不同子系统),那么您将希望将所有与视图相关的内容都保留在插件级别,以便父对象甚至不必知道给定插件所处理的内容,但只需将其返回值放在GUI中的某个位置即可

    其他可能影响您选择的因素是您正在使用的语言和框架(如果有):根据我个人的经验,设计模式与语言无关,因为每种语言(和框架)有自己的优势/劣势,使得某些选择显而易见,而某些选择很难实施


    不管怎么说,只有我的2美分参加讨论!:)

    我认为您讨论的设计模式是mediator

    我已经编写了一个javascript框架,其中包含一个中介

    它的工作原理如下:

    • 您将创建 调解人
    • 将对象注册到 某些名字
    • 在实现中使用中介来调用方法 来自以下任何一个域中的注册对象: 物体
    如果某些东西不存在,就不会有错误。 如果有多个实例,它们都会得到调用

    这是这方面的基本代码: (我的代码摘录。我会在一段时间内制作一个jquery插件,包括它。如果你愿意使用它,请推动我更快地完成;)


    @大卫·默多克。谢谢编辑大卫。大写字母用于指代在我居住的地方有“你”的人。仅供参考:你不应该仅仅因为某件事让你烦恼而编辑别人的答案[按要求写一封小信]。有人可能会生气。
    function Mediator(){
    
        function log(a){
        try {console.log(a);} catch(e){
            try {opera.postError(a);} catch(e){
                //alert(a);
                }
            }
        }
    
        var __reg={}; // { "what": [object, ...], ... }     //registers an object
        //what=key that will identify, obj=an object
        this._register = function(what,obj){
            if(__reg[what]===undefined){        
                __reg[what]=[];     
                }
            __reg[what].push(obj);      
            }   //unregisters multiple objects and deletes a key
        this._unregisterAll = function(what){
            if(__reg[what]===undefined){log('Overlord:_unregisterAll - no registers'); return false; }
            __reg[what]=null;
            return true;
            }
        //unregisters a single element key
        this._unregister = function(what){
            if(this._countRegisters()==1){
                    __reg[what]=null;
                    return true;
                } else { log('Overlord:_unregister - no registers'); return false; }
            }
        //unregisters last added element
        this._unregisterLast = function(what){
            var cnt=this._countRegisters(what);
            if(cnt==0) { log('Overlord:_unregisterLast - no registers'); return false; }
            if(cnt==1) {
                    __reg[what]=null;
                    return true;
                } else {
                    __reg[what][cnt-1]=null;
                    return true;
                }
            }
    
        //returns number of registered items
        this._countRegisters = function(what){
            try{
                return __reg[what].length;
                } catch(e){log(e);
                return 0;
                }
            }   //calls a method from all objects registered under 'what' with an array of parameters. returns true if there was at least one successful call
        this._call = function(what,method,params){
            var occured=false;
            for(var i in __reg[what]) {
                try {
                    __reg[what][i][method](params);
                    occured=true;
                    } catch(e) {log(e);//auto reakcja           
                    }
                }
            return occured;
            }
        //does the call, but also returns an array of values retuurned by function
        this._returnAll = function(what,method,params){
            var re=[];
            for(var i in __reg[what]){
                try {
                    re.push(__reg[what][i][method](params));
                    } catch(e) {log(e);//auto reakcja           
                    }           
                }
            return re;
            }
    
        //runs a method from first object for a given key   
        this._returnFirst = function(what,method,params){
            try {
                return __reg[what][0][method](params);
                } catch(e) {log(e);//auto reakcja
                return null;
                }
            }
    
        }