草庐IT

关于extjs:动态管理Ext.app.Application.controllers

codeneng 2023-03-28 原文

dynamically manage Ext.app.Application.controllers

目前,我们的团队正在评估使用 ExtJS 作为前端转换大型企业 Web 应用程序(一种 ERP 系统,600 个独特的屏幕)的可能性。该应用程序是基于我们的开源 eludia 引擎构建的

我们的引擎需要模型定义(当您编辑定义时它会变形数据库),有某种控制器
(内容模块)和演示文稿(带有生成实际 js html 混合代码的演示模块)

就像这个帖子中的一些人一样,我们的团队有一个问题:

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

目前 eludia 核心开发人员(=我的团队,我们同时维护这个应用程序和 eludia)已经完成了一些步骤,以使用 ExtJS 作为前端的变形引擎

我的团队正在考虑:

  • 继续使用旧的内容模块作为服务器端代码
  • 使用服务器端模型定义即时为 ExtJS 生成模型文件,
  • 将 Presentation 模块转换为客户端 ExtJS 视图模块,并为每个屏幕编写客户端控制器
    但是现在又多了一个问题:ExtJS 需要枚举 Ext.app.Application 中的所有控制器
    每次一个人写新的/转换旧引擎的屏幕时,他都应该将它添加到这个列表中

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

因此这些问题按模糊程度排序:

  • 你能说出任何使用 ExtJS 作为前端的足够大(600 个屏幕,最好是开源的)MVC/非 MVC 应用程序吗?
  • 我们是否以正确的方式前进?

更新

我应该尽量缩小问题的范围

应用启动时不需要一次性加载所有控制器吗?

我想说的是,也许可以以更"动态"的方式加载控制器:

  • 为打开的屏幕生成一个控制器js
  • 将新的附加到 Ext.app.Application.controllers
    每当用户做某事(点击链接、按钮等)时:需要新屏幕时

  • 控制器通常包含业务逻辑,那么如果您的业务逻辑特定于您的应用程序,您希望如何以一般方式生成控制器?还是您只想为模型生成 CRUD 操作?如果是这样,您可以考虑创建通用控制器,它将适用于不同类型的模型。但是如果您的控制器不同,那么(如果我理解正确的话)您需要通过 AJAX 调用从服务器加载这些控制器,对吗?请澄清。
  • 是的,我需要通过 AJAX 调用从服务器加载这些控制器,而不是一次全部加载


最好的办法是依赖 Ext.Loader,但不要使用上面建议的 loadScriptFile() 方法。

Ext 4 引入了一个类系统。其(许多)好处之一是 dep-tree,它允许您管理所有组件间依赖项并根据需要加载类。

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

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

定义一个动态加载的控制器类:

1
2
3
4
5
6
7
8
9
10
11
12
13
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(){}

 // [...]

现在动态加载你的控制器类(一个模型):

1
2
3
4
5
6
7
8
9
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() 方法。

1
2
3
4
5
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()
}

更多阅读:

  • http://docs.sencha.com/ext-js/4-0/#!/guide/class_system
  • http://docs.sencha.com/ext-js/4-0/#!/guide/application_architecture

按需使用控制器的最佳方式是动态加载它们并在需要时创建控制器实例。您还需要将控制器放在单独的 js 文件中,因此架构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//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);
}

更新
为了将新控制器集成到已经运行的 Ext.app.Application 中,您需要扩展 Ext.app.Application 并添加以下方法:

1
2
3
4
5
6
7
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);
}

顺便说一句,您可以使用 Ext.Loader:

的 ExtJs 内置方法,而不是使用自定义方法动态加载 javascript 文件

1
2
3
4
5
6
7
8
9
10
/**
         * 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)

  • 我知道如何创建/加载控制器,我只是不确定如何在运行 ExtJS 应用程序中"插入"


我们刚刚使用我们的 web 应用程序完成了这个过程。约 250 个屏幕。是的,我们动态加载我们的控制器。

使用 Ext.JS 构建屏幕的时间比使用 YUI(我们之前的平台)快 400%。不错的是我们可以保留 YUI Connect 对象,它比 Ext.JS 版本更高效。

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

我假设您想动态加载这些控制器以缩短加载时间(这也是我们最初也遇到的问题)。扩展,扩展,扩展。

1
2
3
4
5
Ext.define('namespace.classname', {
{
    extend: 'Ext.form.panel',
    // your code here
}

这将降低您的整体代码下载速度,并加快初始化速度。

  • 这是人在做类似于我想要的事情:stackoverflow.com/questions/6290729/...好点,会调查它,谢谢!


我在这里问了同样的问题: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 的初始配置之外,我不会做任何影响视图的事情(这一切都在基类中处理)。大多数类都将处理程序和其他东西附加到面板以提供特定于应用程序的行为,这基本上是控制器的定义。在我看来,它并不完美,但它比当前的替代方案要好。

如果您想了解我所说的任何示例,或者对我的具体实施有疑问,请告诉我,我很乐意为您提供帮助。


虽然我不知道这是否可行(从未尝试过),但我会看的是 Ext.app.Application.getController() 方法。来自 api 参考:

Returns instance of a controller with the given name. When controller doesn't exist yet, it's created.

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

我在查看 Ext 4 时了解到的一个旁注。控制器不能触发事件,因此您必须在控制器之间进行通信时触发 Application 对象上的事件,如本文所述

有关关于extjs:动态管理Ext.app.Application.controllers的更多相关文章

  1. ruby - i18n Assets 管理/翻译 UI - 2

    我正在使用i18n从头开始​​构建一个多语言网络应用程序,虽然我自己可以处理一大堆yml文件,但我说的语言(非常)有限,最终我想寻求外部帮助帮助。我想知道这里是否有人在使用UI插件/gem(与django上的django-rosetta不同)来处理多个翻译器,其中一些翻译器不愿意或无法处理存储库中的100多个文件,处理语言数据。谢谢&问候,安德拉斯(如果您已经在ruby​​onrails-talk上遇到了这个问题,我们深表歉意) 最佳答案 有一个rails3branchofthetolkgem在github上。您可以通过在Gemfi

  2. ruby-on-rails - 渲染另一个 Controller 的 View - 2

    我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>

  3. ruby-on-rails - Rails 应用程序中的 Rails : How are you using application_controller. rb 是新手吗? - 2

    刚入门rails,开始慢慢理解。有人可以解释或给我一些关于在application_controller中编码的好处或时间和原因的想法吗?有哪些用例。您如何为Rails应用程序使用应用程序Controller?我不想在那里放太多代码,因为据我了解,每个请求都会调用此Controller。这是真的? 最佳答案 ApplicationController实际上是您应用程序中的每个其他Controller都将从中继承的类(尽管这不是强制性的)。我同意不要用太多代码弄乱它并保持干净整洁的态度,尽管在某些情况下ApplicationContr

  4. ruby-on-rails - rails : How to make a form post to another controller action - 2

    我知道您通常应该在Rails中使用新建/创建和编辑/更新之间的链接,但我有一个情况需要其他东西。无论如何我可以实现同样的连接吗?我有一个模型表单,我希望它发布数据(类似于新View如何发布到创建操作)。这是我的表格prohibitedthisjobfrombeingsaved: 最佳答案 使用:url选项。=form_for@job,:url=>company_path,:html=>{:method=>:post/:put} 关于ruby-on-rails-rails:Howtomak

  5. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  6. ruby-on-rails - 每次我尝试部署时,我都会得到 - (gcloud.preview.app.deploy) 错误响应 : [4] DEADLINE_EXCEEDED - 2

    我是Google云的新手,我正在尝试对其进行首次部署。我的第一个部署是RubyonRails项目。我基本上是在关注thisguideinthegoogleclouddocumentation.唯一的区别是我使用的是我自己的项目,而不是他们提供的“helloworld”项目。这是我的app.yaml文件runtime:customvm:trueentrypoint:bundleexecrackup-p8080-Eproductionconfig.ruresources:cpu:0.5memory_gb:1.3disk_size_gb:10当我转到我的项目目录并运行gcloudprevie

  7. ruby-on-rails - 如何在 Rails Controller Action 上触发 Facebook 像素 - 2

    我有一个ruby​​onrails应用程序。我按照facebook的说明添加了一个像素。但是,要跟踪转化,Facebook要求您将页面置于达到预期结果时出现的转化中。即,如果我想显示客户已注册,我会将您注册后转到的页面作为成功对象进行跟踪。我的问题是,当客户注册时,在我的应用程序中没有登陆页面。该应用程序将用户带回主页。它在主页上显示了一条消息,所以我想看看是否有一种方法可以跟踪来自Controller操作而不是实际页面的转化。我需要计数的Action没有页面,它们是ControllerAction。是否有任何人都知道的关于如何执行此操作的gem、文档或最佳实践?这是进入布局文件的像素

  8. ruby-on-rails - 获取 inf-ruby 以使用 ruby​​ 版本管理器 (rvm) - 2

    我安装了ruby​​版本管理器,并将RVM安装的ruby​​实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby​​。有没有办法让emacs像shell一样尊重ruby​​的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el

  9. ruby-on-rails - 如何重命名或移动 Rails 的 README_FOR_APP - 2

    当我在我的Rails应用程序根目录中运行rakedoc:app时,API文档是使用/doc/README_FOR_APP作为主页生成的。我想向该文件添加.rdoc扩展名,以便它在GitHub上正确呈现。更好的是,我想将它移动到应用程序根目录(/README.rdoc)。有没有办法通过修改包含的rake/rdoctask任务在我的Rakefile中执行此操作?是否有某个地方可以查找可以修改的主页文件的名称?还是我必须编写一个新的Rake任务?额外的问题:Rails应用程序的两个单独文件/README和/doc/README_FOR_APP背后的逻辑是什么?为什么不只有一个?

  10. ruby - Sinatra set cache_control to static files in public folder编译错误 - 2

    我不知道为什么,但是当我设置这个设置时它无法编译设置:static_cache_control,[:public,:max_age=>300]这是我得到的syntaxerror,unexpectedtASSOC,expecting']'(SyntaxError)set:static_cache_control,[:public,:max_age=>300]^我只想将“过期”header设置为css、javaascript和图像文件。谢谢。 最佳答案 我猜您使用的是Ruby1.8.7。Sinatra文档中显示的语法似乎是在Ruby1.

随机推荐