2011-10-11 48 views
10

目前,我们团队评估使用ExtJS作为前端转换大型企业Web应用程序(一种ERP系统,600多种独特的屏幕)的可能性。我们的引擎需要模型定义(它可以在编辑定义时变形数据库),拥有某种控制器 (内容模块)和演示文稿(演示模块带有生成实际js的代码) + HTML混合)动态管理Ext.app.Application.controllers

像一些人this线程我们的团队有一个问题:

我们希望有模型和视图在服务器端,只是JSON数据发送到前端

当前e ludia核心开发人员(=我的团队,我们同时维持该应用程序和eludia)也做了一些步骤,向变形引擎使用ExtJS的作为前端

我的团队正在考虑:

  • 继续使用原有的内容模块,服务器端代码
  • 生成模型文件使用服务器端模型定义上飞ExtJS的,
  • 转换演示模块,以客户端ExtJS的视图模块,和写入每个屏幕 客户机侧控制器但现在有一个更多问题:ExtJS需要枚举所有在Ext.app.Application 每当一个人写新的控制器/转换从旧引擎的屏幕,他应该将它添加到这个列表

可以Ext.app.Application.controllers ...动态生成?

因此,这些问题由模糊下令:

  • 你能说出个足够大(600个+屏幕,最好开源)MVC /非MVC它使用ExtJS的为前端应用程序?
  • 我们正在以正确的方式移动吗?

UPDATE

我应该尽量窄的问题

一个并不需要的应用程序启动时,一次加载所有控制器?

我想说,也许这是可能加载控制器更“动态”的方法是什么:

  • 生成一个控制器JS的打开屏幕
  • 追加新的以Ext.app.Application .controllers 每当用户做一些其它事情(点击一个链接,按钮等):当需要新的屏幕
+0

控制器通常包含业务逻辑,所以你要如何生成,如果你的业务逻辑一般方式控制器是特定于您的应用程序?或者你想为你的模型生成刚才的CRUD操作?如果是这样,你可以考虑创建通用控制器,它将与不同类型的模型一起工作。但是如果你的控制器不同,那么(如果我理解你正确),你需要通过AJAX调用从服务器加载这些控制器,对吧?请澄清。 –

+0

是的,我需要通过AJAX调用从服务器加载这些控制器,并不是所有的一次 – jonny

回答

0

虽然我不知道这是否会工作(没试过),我会看,就是Ext.app.Application.getController()方法。从api reference

返回具有给定名称的控制器的实例。当控制器尚不存在时,它就创建了。

因此理论上,您可以使用动态定义的控制器调用getController(),它将创建它。

一个侧面说明,我一边看着分机4.控制器不能触发事件教训,所以你要做的控制器之间的通信是什么火了Application对象上的事件,在this post

0

我描述在这里问同样的问题:http://www.sencha.com/forum/showthread.php?151220-Adding-controllers-views-dynamically-in-Ext-MVC-pattern

它似乎并没有在当前的Ext 4中得到很好的支持。自从我转向以来,我没有使用Ext提供的MVC架构,而是使用相同的我在Ext 3中使用的技术,在某些处理程序上添加/加载附加组件(按钮或链接点击,悬停,搜索等) 。

在我的应用程序中,我所有的组件都是基本Ext类的自定义扩展,最终的作用就像一个控制器,超类是视图。例如,如果我的扩展名为Ext.panel.Panel,除了初始配置itemslayout之外,我没有做任何影响视图的事情(这些都是在基类中处理的)。大多数类将附加处理程序和其他东西附加到面板以提供特定于应用程序的行为,这基本上是控制器的定义。这并不完美,但在我看来,它比目前的选择更好。

如果您需要我正在谈论的任何示例,或者对我的具体实施有疑问,请告诉我,我很乐意提供帮助。

6

您使用控制器按需的最佳方式是动态加载它们并在需要时创建控制器实例。另外你需要把你的控制器单独的js文件,这样的模式将是以下几点:

//let's say you need to use controller User: 
var controller = ControllerManager.get('User');//I believe you have some controller manager, similar to Sencha's Ext.ControllerManager 
if(controller){ 
//use it here 
} 
else { 
    loadScript([url of your controller script], controllerLoaded); 
} 
... 
function controllerLoaded(){ 
//create controller instance here if needed and use it then 
} 
... 
function loadScript(url, callback){ 

    var script = document.createElement("script") 
    script.type = "text/javascript"; 

    if (script.readyState){ //IE 
     script.onreadystatechange = function(){ 
      if (script.readyState == "loaded" || 
        script.readyState == "complete"){ 
       script.onreadystatechange = null; 
       callback(); 
      } 
     }; 
    } else { //Others 
     script.onload = function(){ 
      callback(); 
     }; 
    } 

    script.src = url; 
    document.getElementsByTagName("head")[0].appendChild(script); 
} 

UPDATE 为了新的控制器整合到已经运行Ext.app.Application您需要扩展Ext.app.Application并添加以下方法:

addController: function(name){ 
    //at this point your controller .js file should be already loaded into the DOM 
    var c = this.getController(name); //controller will be created automatically by name in this getter 
    //perform the same initialization steps as it would have during normal ExtJs process 
    c.init(this); 
    с.onLaunch(this); 
} 

顺便说一句,而不是使用自定义的方法来加载javascript文件动态,你可以使用ExtJS的的Ext.Loader内置方法:

/** 
     * Load a script file, supports both asynchronous and synchronous approaches 
     * 
     * @param {String} url 
     * @param {Function} onLoad 
     * @param {Object} scope 
     * @param {Boolean} synchronous 
     * @private 
     */ 
     loadScriptFile: function(url, onLoad, onError, scope, synchronous) 
+0

我知道如何创建/加载控制器,我只是不知道如何'插入'在运行ExtJS应用程序 – jonny

+0

请找到我的回复更新到帖子 –

1

我们刚刚通过我们的网络应用程序经历了这一点。 〜250个屏幕。是的,我们动态加载我们的控制器。

使用Ext.JS创建屏幕的时间比使用YUI(这是我们以前的平台)快了400%。好的一点是,我们可以保持YUI Connect对象的效率比Ext.JS版本更好。

我们有一个App类来管理Ext.JS控制器的加载和初始化。在这里,我们使用YUI.get(YUI.get.script)代码中唯一的其他YUI类。只要确保在同一个会话中不加载控制器两次。

我假设你想动态加载这些控制器的加载时间(这也是我们最初的努力)。 EXTEND,EXTEND,EXTEND。

Ext.define('namespace.classname', { 
{ 
    extend: 'Ext.form.panel', 
    // your code here 
} 

这会降低你的整体代码下载,并加快初始化。

+0

这里是男人做类似于我想要的东西:http://stackoverflow.com/questions/6290729/how-to-use-ext-define-in-extjs4好点,将调查它, 谢谢! – jonny

6

最好的办法是依靠Ext.Loader,但不要使用loadScriptFile()方法如上所述。

分机4引入了一个类系统。其中一个(许多)好处是dep-tree,允许您根据需要管理所有组件间依赖关系和加载类。

这里是你如何初始化加载器

Ext.Loader.setPath('App','/js/app'); 
Ext.Loader.setPath('WidgetsLibrary','/js/widgets'); 
Ext.Loader.setConfig({enabled: true}); 

Define动态加载控制器类:

Ext.define('App.controller.Menu', { 
    extend: 'Ext.app.Controller',  // leave it as it is 
    models: ['Event','User'],   // this assumes App.model.* prefix 
    stores: ['Options','Permissions'], // this assumes App.store.* prefix 
    views: ['menu.Bar','SmartButton'],// this assumes App.view.* prefix 
    requires: [ 
     'App.whatever.other.class', // auto-load this class as a dependency 
     'WidgetsLibrary.*',   // auto-load all classes in WidgetsLibrary 
    ], 

    init: function(){} 

// [...] 

我们dynamically-load您的控制器类(一个样机):

Ext.require(     
    'App.controller.Menu',  // this auto-loads all dependencies 
    function(){ 
     // ... as soon as this class 
     // and all its dependencies have loaded... 
     var controller = Ext.create('App.controller.Menu'); // create an instance 
     controller.init();         // launch init() method 
    } 
); 

奖励:通过使用类系统和加载器,您不必维护自己的控制器集合并检查控制器是否已加载。只需使用Ext.ClassManager.isCreated()method described here即可。

if(Ext.ClassManager.isCreated('App.controller.Menu')){ 
    // ... controller has already been loaded and init ... 
}else{ 
    // we need to auto-load that controller using Ext.require() 
} 

更多阅读:

+0

+1精确简洁 –