一个Extjs应用程序调用另一个Extjs APP [英] An Extjs App Calling another Extjs APP

查看:150
本文介绍了一个Extjs应用程序调用另一个Extjs APP的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用Sencha Cmd生成工作空间并创建两个不同的应用程序后,我只想运行第一个应用程序,然后单击按钮后,调用第二个应用程序:)
像一个主应用程序调用另一个子程序, app
有没有办法呢?
thx为您的帮助

解决方案

您可以开发分离的模块,可以一起工作,没有问题。这两个概念根本没有冲突。



让我分享一下我的经验。当我们开始我们目前的项目(从头开始)时,还有另外两个团队开发了另外两个应用程序,在一段时间之后,我们应该将它们集成到一个大的应用程序中。你不必是一个预测结局的天才,对吧?事情变得更糟,当我们听到客户想要更多的并行工作(更多的团队开发模块)。



第一个想法是使用iframe,但是PoC证明这是一个坏主意,我们停止了机器,并开始设计一个可插拔的架构。我们做得很好,因为目前我们可以轻松加载以孤立的方式开发的模块(我们称之为插件)。例如,看看我们的文件夹结构如何:





这是我们设置要加载的模块的元数据:



这有很多优点:




  • 模块可以并行开发,

  • 模块可以单独测试,

  • 模块可以动态加载,启用或禁用



当然,这不是extjs提供开箱即用的东西,这样做是因为它值得。



所以,简短的答案:你的问题不是应用程序的大小,而是它的结构。按照推荐的MVC模式,使用自定义文件夹结构。



更新:



关于插件元数据。应用程序主控制器只有一个责任:加载插件。这是通过以下代码完成的:

  discoverPlugins:function(){
var me = this;
Ext.each(plugins(),function(d){
me.loadPluginController(d.controller);
});

App.History.notifyAppLoaded();
},

loadPluginController:function(controllerName){
try {
var controller = App.current.getController(controllerName);
controller.init(App.current);
} catch(e){
console.log(controllerName +'controller can not be loaded。'+ e);
}
},

每个插件控制器都作为调度员,是,有一个历史组件监听url(在地址栏中),当它改变时,通过插件迭代插件来处理url。该过程在插件能够处理所请求的URL时结束。

这是操作插件的调度程序配置:

 构造函数:function(){
this.callParent(arguments);
this.router.set({
'!/ operations / product / permissions / definition':this.viewPermissionsDefinition,
'!/ operations / product / accesslist / create':this.createProductAccessList ,
'!/ operations / product / accesslist / {id} / edit':this.editProductAccessList
'!/ operations / product / accesslist / {id}':this.viewProductAccessList,
'!/ operations / product / accesslist':this.viewProductAccessList,
'!/ operations / {...}':this.notFound,
'!/ operations':this.root
});
}

这是历史类代码的导航方法:

 导航:function(token){
var me = this,
processed;

if(token){
processed = false;
for(var i = 0; i< me.routers.length; i ++){
if(me.routers [i] .processToken(token)){
processed = true;
break;
}
}

if(!processed){
App.current.fail(404,'Resource not found。');
}
} else {
App.current.gotoUrl('/ servicedesk / search');
}
},

一个重要的一点是插件只有一个引用一个共享组件:它们呈现的中心区域:

  refs:[
{ref:'main'选择器:'#center-panel'}
],

此引用由所有插件控制器是AbstractPluginController的子类。这是重要的,因为它是唯一的模块知道他们的主机。这就是为什么我们可以并行开发。



关于AbstractPluginController,这个相同的类有一些核心功能对所有的插件控制器有用,例如,为了加载所有他们的控制器/视图/模型是必需的,而不是之前,此类实现动态控制器加载如下:

  createControllerGetters :function(controllers){
var me = this;
controllers = Ext.Array.from(controllers);
Ext.Array.each(controllers,function(controllerName){
var parts = controllerName.split('。'),
idx = parts.indexOf('controller'),
significantants = parts.slice(idx + 1),
name = significantants.map(function(e){return Ext.String.capitalize(e);})。join(''),
fn ='get'+ name +'Controller';

if(!me [fn]){
me [fn] = Ext.Function.pass(me.getController, controllerName],me);
}
});
},

getController:function(controllerName){
this.controllerCache = this.controllerCache || {};
var me = this,
cached = me.controllerCache [controllerName];

if(!cached){
me.controllerCache [controllerName] = cached = App.current.getController(controllerName);
if(cached){
cached.init();
cached.on('beforedestroy',function(){
me.controllerCache [ref] = null;
});
}
}

返回缓存;
},

这允许我们指定子控制器列表(因为主控制器是只是一个初始化程序和调度),该模块已经允许我们根据需要创建它们。

  controllers:[
'operation.controller.ProductAccessListViewer',
'Operation.controller.ProductAccessListEditor',
'Operation.controller.ProductAccessListCreator'
],

总结:我认为要点是:



  1. 通过链接导航/通信,主要是使用元数据(插件可以暴露额外的元数据)

  2. 懒惰的控制器加载(他们做自己的意见)



希望这样给你一个想法。有很多细节需要一些技巧来整合它们,但基本上,我想在这里显示的是一个模块化应用程序可以(或应该)开发与extjs只需一点额外的努力。


after generating a Workspace using Sencha Cmd and create Two different app, i just want to Run the first app and then after clicking a button,it calls the second app :) Like A main app calling another sub-app is there a way to do it ? thx for your help

解决方案

You can develop separated modules that can work together with no problems. Both concepts are no in conflict at all.

Let me share my experience here. When we started in our current project (from the scratch) there were other two teams developing another two applications which after some time we should 'integrate' them in just one big app. You don´t have to be a genius to predict the ending result, right? Things got worse when we heard customer wanted more parallel work (more teams developing modules).

The first idea was using iframes but the PoC demonstrated it was a bad idea so, we stopped the machine and started designing a pluggable architecture. We did it well because currently we are able to load modules (we called it plugins) developed in an isolated way easily. For example, take a look at how our folder structure looks like:

And this is the metadata where we set the modules we want to load:

This has a lot of advantages:

  • modules can be developed in parallel,
  • modules can be tested isolated,
  • modules can be loaded dynamically, enabled or disabled

Of course, this is not something extjs provides out of the box but you can do it because it worth.

So, short answer: your problem is not the application´s size but its struture instead. Follow the recommended MVC pattern with a custom folder structure as we do.

Update:

About the plugins metadata. The application main controller has only one responsability: load the plugins. This is done with this code:

discoverPlugins: function () {
    var me = this;
    Ext.each(plugins(), function (d) {
        me.loadPluginController(d.controller);
    });

    App.History.notifyAppLoaded();
},

loadPluginController: function (controllerName) {
    try {
        var controller = App.current.getController(controllerName);
        controller.init(App.current);
    } catch (e) {
        console.log(controllerName + ' controller couldn\'t be loaded.' + e);
    }
},

And every plugin controller acts as a dispatcher, this is, there is a history component listening the url (in the address bar) and when it changes, iterates plugin by plugin asking for handle the url. The process ends when a plugin is able to handle the requested url.
This is the dispatcher configuration for the 'operations' plugins:

constructor: function () {
    this.callParent(arguments);
    this.router.set({
        '!/operations/product/permissions/definition': this.viewPermissionsDefinition,
        '!/operations/product/accesslist/create': this.createProductAccessList,
        '!/operations/product/accesslist/{id}/edit': this.editProductAccessList,
        '!/operations/product/accesslist/{id}': this.viewProductAccessList,
        '!/operations/product/accesslist': this.viewProductAccessList,
        '!/operations/{...}': this.notFound,
        '!/operations': this.root
    });
} 

And This is the navigate method of the history class code:

navigate: function (token) {
    var me = this,
        handled;

    if (token) {
        handled = false;
        for (var i = 0; i < me.routers.length; i++) {
            if (me.routers[i].processToken(token)) {
                handled = true;
                break;
            }
        }

        if (!handled) {
            App.current.fail(404, 'Resource not found.');
        }
    } else {
        App.current.gotoUrl('/servicedesk/search');
    }
},

One important point is plugins only have a reference to one shared component: the center area where they are rendered:

refs: [
    { ref: 'main', selector: '#center-panel' }
],

This reference is inherited by all the plugin controllers which are subclasses of a 'AbstractPluginController'. This is important because is the only thing modules know about their hoster. And this is why we can develop in parallel.

About the AbstractPluginController, this same class has some core functionalities useful for all the plugin controllers, for example, in order to load all theirs controllers/views/models when are required and not before that, this class implements the dynamic controllers loading as follow:

createControllerGetters: function (controllers) {
    var me = this;
    controllers = Ext.Array.from(controllers);
    Ext.Array.each(controllers, function (controllerName) {
        var parts = controllerName.split('.'),
            idx = parts.indexOf('controller'),
            significants = parts.slice(idx + 1),
            name = significants.map(function (e) { return Ext.String.capitalize(e); }).join(''),
            fn = 'get' + name + 'Controller';

        if (!me[fn]) {
            me[fn] = Ext.Function.pass(me.getController, [controllerName], me);
        }
    });
},

getController: function (controllerName) {
    this.controllerCache = this.controllerCache || {};
    var me = this,
        cached = me.controllerCache[controllerName];

    if (!cached) {
        me.controllerCache[controllerName] = cached = App.current.getController(controllerName);
        if (cached) {
            cached.init();
            cached.on('beforedestroy', function () {
                me.controllerCache[ref] = null;
            });
        }
    }

    return cached;
},

This allows us to specify the list of subcontrollers (because the main controllers is just an initializer and dispatch) the module has, and allows us to create them on demand.

controllers: [
    'Operations.controller.ProductAccessListViewer',
    'Operations.controller.ProductAccessListEditor',
    'Operations.controller.ProductAccessListCreator'
],

Summarizing: I think the main points are these:

  1. modules don´t have to know anything about the host application.
  2. navigation/communication through links, mostly
  3. integration performed by the host using metadata (plugins can expose extra metadata too)
  4. lazy loading of controllers (they do the something with their own views)

I hope this gives you an idea. There are lots of details an some tricks to integrate them but basically, what i want to show here is a modular application can be (or should be) developed with extjs with just a little of extra effort.

这篇关于一个Extjs应用程序调用另一个Extjs APP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆