`
wangangie20
  • 浏览: 45771 次
  • 性别: Icon_minigender_2
  • 来自: 厦门
最近访客 更多访客>>
社区版块
存档分类
最新评论

在应用中使用Ext Loader

 
阅读更多

  
  原文:http://www.sencha.com/blog/using-ext-loader-for-yo ur-application/
  ExtJS 4.0是一个使用新的依赖系统的类加载系统。这两个强大的新功能允许你创建大量允许浏览器按需下载脚本代码的应用。
  今天,我们将通过建立一个小的使用新的类加载系统的应用程序来熟悉一下依赖管理系统。同时,我们将讨论Ext加载系统的各种配置项。
  在开始之前,我们先来看看将要实现的结果。这样做,可使我们确定需要扩展那些类。
  
  应用会包括互相绑定的GridPanel和FormPanel,名称分别为UserGridPanel和UserFormPanel。UserGridPanel的操作需要创建一个模型和Store。UserGridPanel和UserFormPanel将被渲染到一个名称为UserEditorWindow的窗口,它扩张自ExtJS的Window类。所有这些类都会在命名空间MyApp下。
  在开始编码前,首先要确定目录结构,以下是使用命名空间组织的文件夹:
  
  从上图可以看到,MyApp目录已经按照命名空间进拆分成几个目录。在完成开发的时候,我们的应用将会有一个如下图所示的内部依赖运行模型。       (尽管应用的目录构成很象ExtJS 4 MVC架构,事实上示例并没有使用它 ) 
  
  现在开始编写index.html文件,这里需要包含应用需要的启动文件和应用的根文件(app.js)。 1  DOCTYPE HTML PUBLIC  "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
  2   
  3   
  4      Ext 4 Loader 
  5       
  6      
  7       
  8   
  9   
  10   
  11   
  index.html文件中需要使用link标记包含ExtJS 4的样式文件。包含ext-debug.js文件的javascript标记可能要修改多次,ext-all-debug.js文件是开发调试用的,而ext-all.js则是在发布产品时使用的。
  这里有几个选择,每个选择都有优缺点。
  以下是这些文件的说明:
  ext-all-debug-w-comments.js:带注释的的完整调试版本。文件比较大,加载时间比较长。
  ext-all-debug.js : 不带注释的完整调试版本。文件也比较大,但很适合调试。
  ext-all.js ;压缩后的完整版本,文件比较小。使用该版本调试很困难,因此一般在发布产品时才使用。
  ext-debug.js : 该文件只包含ExtJS基础架构和空的结构。使用该文件,可以实现ExtJS类文件的远程加载,而且提供了很好的调试体验,不过代价是相当的慢。
  ext.js : ext-debug.js的压缩版本。
  我们的index.html将使用ext-debug.js文件,这是实现动态加载所需的最低要求。最后,我们将展示如何使用ext-all版本获取最好的结果。
  由于UserGridPanel 类要求模型和Store,因而,要先定义编写这些支持类。现在开始编写模型和Store: 1  Ext.define('MyApp.models.UserModel', { 
  2      extend   : 'Ext.data.Model', 
  3      fields   : [ 
  4          'firstName', 
  5          'lastName', 
  6          'dob', 
  7          'userName' 
  8      ]  9  }); 
  以上代码扩展自Ext.data.Model,将创建UserModel 类。因为扩展自Ext.data.Model类,ExtJS会自动加载它,并在它加载后创建UserModel类。
  下一步,要创建扩展自Ext.data.Store的UserStore 类: 1  Ext.define('MyApp.stores.UserStore', { 
  2      extend    : 'Ext.data.Store', 
  3      singleton : true, 
  4      requires  : ['MyApp.models.UserModel'], 
  5      model     : 'MyApp.models.UserModel', 
  6      constructor : function() { 
  7          this.callParent(arguments); 
  8          this.loadData([ 
  9              { 
  10                  firstName : 'Louis', 
  11                  lastName  : 'Dobbs', 
  12                  dob       : '12/21/34', 
  13                  userName  : 'ldobbs' 
  14              }, 
  15              { 
  16                  firstName : 'Sam', 
  17                  lastName  : 'Hart', 
  18                  dob       : '03/23/54', 
  19                  userName  : 'shart' 
  20              }, 
  21              { 
  22                  firstName : 'Nancy', 
  23                  lastName  : 'Garcia', 
  24                  dob       : '01/18/24', 
  25                  userName  : 'ngarcia' 
  26              } 
  27          ]); 
  28      }  29  }); 
  当创建单件模式的UserStore 时,需要在UserStore原型添加一个requires关键字,它会在类实例化前,为ExtJS提供一个类的请求列表。在这个示例,列表中只有UserModel 一个请求类。
  (实际上,在Store的原型中定义了model为UserModel 类,ExtJS就会自动加载它。在requires关键字中列出的目的,是希望你的代码能自文档化(self-documenting),从而提醒你,UserModel 类是必须的 )
  好了,UserGridPanel视图需要的基类已经创建了,现在可以创建UserGridPanel类了: 1  Ext.define('MyApp.views.UsersGridPanel', { 
  2      extend   : 'Ext.grid.Panel', 
  3      alias    : 'widget.UsersGridPanel', 
  4      requires : ['MyApp.stores.UserStore'], 
  5      initComponent : function() { 
  6          this.store   = MyApp.stores.UserStore; 
  7          this.columns = this.buildColumns(); 
  8          this.callParent(); 
  9      }, 
  10      buildColumns : function() { 
  11          return [ 
  12              { 
  13                  header    : 'First Name', 
  14                  dataIndex : 'firstName', 
  15                  width     : 70 
  16              }, 
  17              { 
  18                  header    : 'Last Name', 
  19                  dataIndex : 'lastName', 
  20                  width     : 70 
  21              }, 
  22              { 
  23                  header    : 'DOB', 
  24                  dataIndex : 'dob', 
  25                  width     : 70 
  26              }, 
  27              { 
  28                  header    : 'Login', 
  29                  dataIndex : 'userName', 
  30                  width     : 70 
  31              } 
  32          ]; 
  33      }  34  }); 
  在上面代码中,要注意requires 关键字,看它是怎么增加UserStore 为请求类的。刚才,我们为GridPanel扩展和Store扩展配置了一个直接的依赖关系。
  下一步,我们要创建FormPanel扩展: 1  Ext.define('MyApp.views.UserFormPanel', { 
  2      extend      : 'Ext.form.Panel', 
  3      alias       : 'widget.UserFormPanel', 
  4      bodyStyle   : 'padding: 10px; background-color: #DCE5F0;' 
  5              + ' border-left: none;', 
  6      defaultType : 'textfield', 
  7      defaults    : { 
  8          anchor     : '-10', 
  9          labelWidth : 70 
  10      }, 
  11      initComponent : function() { 
  12          this.items = this.buildItems(); 
  13          this.callParent(); 
  14      }, 
  15      buildItems : function() { 
  16          return [ 
  17              { 
  18                  fieldLabel : 'First Name', 
  19                  name       : 'firstName' 
  20              }, 
  21              { 
  22                  fieldLabel : 'Last Name', 
  23                  name       : 'lastName' 
  24              }, 
  25              { 
  26                  fieldLabel : 'DOB', 
  27                  name       : 'dob' 
  28              }, 
  29              { 
  30                  fieldLabel : 'User Name', 
  31                  name       : 'userName' 
  32              } 
  33          ]; 
  34      }  35  }); 
  因为UserForm 不需要从服务器端请求任何类,因而不需要添加requires定义。
  应用快完成了,现在需要创建UserEditorWindow类和运行应用的app.js。以下是UserEditorWindow类的代码。因为要将Grid和表单绑定在一起,因而类代码有点长,请见谅: 1  Ext.define('MyApp.views.UserEditorWindow', { 
  2      extend   : 'Ext.Window', 
  3      requires : ['MyApp.views.UsersGridPanel','MyApp.views.UserFormPanel'], 
  4      height : 200, 
  5      width  : 550, 
  6      border : false, 
  7      layout : { 
  8          type  : 'hbox', 
  9          align : 'stretch' 
  10      }, 
  11      initComponent : function() { 
  12          this.items   = this.buildItems(); 
  13          this.buttons = this.buildButtons(); 
  14          this.callParent(); 
  15          this.on('afterrender', this.onAfterRenderLoadForm, this); 
  16      }, 
  17      buildItems : function() { 
  18          return [ 
  19              { 
  20                  xtype     : 'UsersGridPanel', 
  21                  width     : 280, 
  22                  itemId    : 'userGrid', 
  23                  listeners : { 
  24                      scope     : this, 
  25                      itemclick : this.onGridItemClick 
  26                  } 
  27              }, 
  28              { 
  29                  xtype  : 'UserFormPanel', 
  30                  itemId : 'userForm', 
  31                  flex   : 1 
  32              } 
  33          ]; 
  34      }, 
  35      buildButtons : function() { 
  36          return [ 
  37              { 
  38                  text    : 'Save', 
  39                  scope   : this, 
  40                  handler : this.onSaveBtn 
  41              }, 
  42              { 
  43                  text    : 'New', 
  44                  scope   : this, 
  45                  handler : this.onNewBtn 
  46              } 
  47          ]; 
  48      }, 
  49      onGridItemClick : function(view, record) { 
  50          var formPanel = this.getComponent('userForm'); 
  51          formPanel.loadRecord(record) 
  52      }, 
  53      onSaveBtn : function() { 
  54          var gridPanel  = this.getComponent('userGrid'), 
  55              gridStore  = gridPanel.getStore(), 
  56              formPanel  = this.getComponent('userForm'), 
  57              basicForm  = formPanel.getForm(), 
  58              currentRec = basicForm.getRecord(), 
  59              formData   = basicForm.getValues(), 
  60              storeIndex = gridStore.indexOf(currentRec), 
  61              key; 
  62          //loop through the record and set values 
  63          currentRec.beginEdit(); 
  64          for (key in formData) { 
  65              currentRec.set(key, formData[key]); 
  66          } 
  67          currentRec.endEdit(); 
  68          currentRec.commit(); 
  69          // Add and select 
  70          if (storeIndex == -1) { 
  71              gridStore.add(currentRec); 
  72              gridPanel.getSelectionModel().select(currentRec) 
  73          } 
  74      }, 
  75      onNewBtn : function() { 
  76          var gridPanel = this.getComponent('userGrid'), 
  77              formPanel = this.getComponent('userForm'), 
  78              newModel  = Ext.ModelManager.create({}, 
  79                                'MyApp.models.UserModel'); 
  80          gridPanel.getSelectionModel().clearSelections(); 
  81          formPanel.getForm().loadRecord(newModel) 
  82      }, 
  83      onAfterRenderLoadForm : function() { 
  84          this.onNewBtn(); 
  85      }  86  }); 
  UserEditorWindow 的代码包含了许多东西用来管理UserGridPanel和UserFormPanel类的整个绑定的声明周期。为了指示ExtJS在创建该类前加载这两个类,必须在requires列表里列出它们。
  现在完成最后一个文件app.js。为了最大限度地提高我们的学习,将有3次修改要做。首先从最简单配置开始,然后逐步添加。       首先,app.js会在ExtJS添加MyApp命名空间的路径,这可通过调用Ext.loader.setPath方法实现,方法的第1个参数是命名空间,然后是加载文件与页面的相对路径。
  下一步,调用Ext.OnReady方法,传递一个包含Ext.create的匿名函数。Ext.create会在ExtJS 4.0初始化之后执行,以字符串形式传递的UserEditorWindow 类会被实例化。因为不需要指向实例和希望立即显示它,因而在后面串接了show方法的调用。
  如果你打开这个页面(http://moduscreate.com/senchaarticles/01/pass1.htm l ),你会看到UI渲染,但很慢,并且ExtJS会在Firebug中显示以下警告信息:
  
  ExtJS提示我们没有使用加载系统最优化的方式。这是第二步要讨论的问题。然后,这是一个好的学习机会,要好好理由。
  我们需要配置Firebug在控制台中显示XHR请求,以便在控制台中看到所有请求,而不需要切换到网络面板。这样,我们不单可以观察到类依赖系统的工作情况,还可以从所有ExtJS类加载的文件中通过过滤方式找到我们要求这样的文件。
  在Firebug控制台过滤输入框中输入"User",你会看到下图所示的结果。
  
  从图中可以看到,UserEditorWindow类第一个被加载,接着请求UserGridPanel。UserGridPanel 要求UserStore和UserModel类。最后加载UserFormPanel 类。
  我刚才提到,ExtJS提示了我们没有使用加载系统最优化的方式。这是因为依赖是在Ext.OnReady触发加载之后通过同步XHR请求确定的,而这不是有效的方式且难于调试。
  未来修正这个问题,可以修改app.js指示ExtJS先加载我们定义的类,这样即可提供性能又便于调试:       为了快速加载我们定义的类和避免调试信息,可简单的在Ext.onReady前调用Ext.require,只是ExtJS请求UserEditorWindow类。这将会让ExtJS在文档HEAD标记内注入一个script标记,运行资源在Ext.OnReady前加载。
  查看http://moduscreate.com/senchaarticles/01/pass2.htm l 可看到它是如何工作地。在页面加载后,你会注意到ExtJS没有在控制台显示警告信息了。
  我们所做的是让ExtJS框架和应用类延迟加载。虽然这样做调试很好,但是对于需要快速调试的情况,页面渲染时间会让你感到痛苦。为什么?
  原因很简单,因为这需要加载许多资源文件。在示例中,ExtJS发送了193个Javascript资源请求到web服务器,还有部分是在缓存中的:
  
  我们创建了6个Javascript文件(5个类文件和app.js),这意味着加载要求的ExtJS文件有187个请求。当你在本地做开发的时候,这个方案可行,但不是最理想的和效果最好的。
  解决这个问题,我们可以使用折中方案,通过ext-all-debug加载ExtJS框架,动态加载我们的类文件。要实现这个,需要修改两个文件。
  首先,需要修改Index.html,使用ext-all-debug.js替换ext.debug.js。       接着,修改app.js,开启Ext.Loader: 1  (function() { 
  2      Ext.Loader.setConfig({ 
  3          enabled : true, 
  4          paths   : { 
  5              MyApp : 'js/MyApp' 
  6          } 
  7      });  8   
  9      Ext.require('MyApp.views.UserEditorWindow'); 
  10   
  11      Ext.onReady(function() { 
  12          Ext.create('MyApp.views.UserEditorWindow').show(); 
  13      }); 
  14  })(); 
  通过调用Loader.setConfig可开启Ext.Loader,需要传递一个匿名对象,它的eanbled属性设置为true,而命名空间设置为路径映射。
  通过编辑app.js,在本地开发环境下,应用将会在1秒内完成加载和渲染。
  
  源代码下载地址:http://moduscreate.com/senchaarticles/01/files.zip
  作者:
  Jay Garcia
  Author of Ext JS in Action and Sencha Touch in Action , Jay Garcia has been an evangelist of Sencha-based JavaScript frameworks since 2006. Jay is also Co-Founder and CTO of Modus Create , a digital agency focused on leveraging top talent to develop high quality Sencha-based applications. Modus Create is a Sencha Premier partner.
分享到:
评论

相关推荐

    Ext Js权威指南(.zip.001

    9.8.2 在单页面应用中使用卡片布局实现“页面”切换 / 496 9.9 本章小结 / 498 第10章 重构后的grid / 500 10.1 grid的基类及其构成 / 500 10.1.1 概述 / 500 10.1.2 表格面板的运行流程:ext.panel.table / ...

    package-loader:Ext JS 动态包加载器

    在 Cmd 应用程序中使用只需将package-loader添加到'app.json'文件的requires数组中: "requires": [ "package-loader"]然后构建应用程序 sencha app build --devpackage-loader包会自动从 Sencha 的 CDN 下载。...

    ExtJS4中文教程2 开发笔记 chm

    在Extjs4应用中使用Ext.Loader ======================================= 11条jquery常用技巧和方法整理列表 8个超棒的学习jQuery的网站 JQuery 1.5 getJSON 的使用 JQuery AJAX提交中文乱码的解决方案 Jquery css...

    govuk-frontend-jinja:将GOV.UK设计系统与使用Jinja2和Flask的Python Web应用程序结合使用的工具:snake:

    该Python软件包包含一些类和模块,在基于Python网络应用中使用。 注意:该存储库由GDS开发人员维护,但不由GOV.UK设计系统团队维护。 如果您有任何疑问或需要支持,请针对此存储库提出问题。 正在安装 pip install...

    SenchaCmd-3.1.0.192-windows.exe

    现在又多种多样的配置选项可以使用在 ”.sencha/app/sencha.cfg“文件夹下,在只有一张页面的情况下,可以忽略”.sencha/workspace“配置文件夹 classpath类路径 ---------------------------------- sencha app ...

    extjs-grid-converter:将 extjs 网格面板转换为其他内容(如 html 表或 ods 文件)的助手

    extjs-grid-converter 将 extjs 网格面板转换为其他内容(如 html 表或 ods 文件)的助手GridToHtmlTable 当您需要打印或以某种方式导出 exjs 应用程序中显示的网格数据时,请使用此转换器。 此转换器还会转换嵌套列...

    app-extension-apollo:用于Apollo和GraphQL的官方Quasar应用程序扩展-目前是Beta版!

    应用程序扩展-阿波罗 声明书分行职能线数 这是将GraphQL添加到您的Quasar项目中的官方Quasar App-...为了使正常工作,您必须打开一个特殊的转换,以使vue-loader不会在这些新标签上失败。 将以下代码添加到quasar.co

    linux操作系统培训资料.pptx

    Linux操作系统培训 linux操作系统培训资料全文... Linux文件管理 Linux系统中使用的文件类型 目前linux采用的文件系统有ext3文件系统,但是在嵌入式linux操作系统中更多的使用的是jffs2,yaffs和nfs网络文件系统。 Jffs2

    grunt-extjs:Grunt 的 ExtJS 路径和​​依赖项生成器

    grunt-extjs v0.1.3 生成 ExtJS 路径和​​依赖项。入门这个插件需要 Grunt ~0.4.0 如果您以前没有使用过 ,请务必查看指南... 然后您的 ExtJS 应用程序将被生成(即由 Node 实例化)以通过Ext.Loader查找您的所有依赖E

    twinkle-enwiki:围绕Twinkle核心的Enwiki本地化

    这将调用 ,每次代码更改时都会刷新浏览器中的应用程序。 可以通过访问捆绑的应用程序,您可以将其导入到维基百科的common.js页面。 您还需要提供依赖项: 以下内容可以在: mw . loader . using ( 'ext.gadget....

    深入分析Linux内核源码

    1.5.1 Linux内核在整个操系统中的位置 1.5.2 Linux内核的作用 1.5.3 Linux内核的抽象结构 1.6 Linux内核源代码 1.6.1 多版本的内核源代码 1.6.2 Linux内核源代码的结构 1.6.3 从何处开始阅读源代码 ...

    AlertBox:Extjs 4 警报框小部件

    Yan Shi - ExtJS 4 Alert Box ExtJS 4 应用程序的可关闭警报框 用法 在您的应用程序文件中,请添加: Ext.Loader.setConfig({enabled: true})

    extract-text-webpack-plugin用法详解

    打包样式有两种方法,一种是使用style-loader自动将css代码放到生成的style标签中,并且插入到head标签里。另一种就是使用extract-text-webpack-plugin插件,将样式文件单独打包,打包输出的文件由配置文件中的...

    AT91SAM9263开发板SBC6300X.rar

    支持3.5、4.3、5.6、7寸LCD液晶屏,可在高达800*480分辩率下流畅显示 l 预装Microsoft WinCE 6.0或Linux 2.6操作系统,提供相关驱动源码 l 提供全部板载外设驱动程序说明及相关测试程序 UploadFile/2009/09/...

    oracle truncate恢复

    2. 我们OFFLINE掉DB_JJ_INFO_TEMP表的表空间(实际上在实际的系统中,如果有比较多的活动,则表空间不容易被OFFLINE下来)。然后做一个Checkpoint,让ODU能够读到最新的数据字典数据。 SQL> select tablespace_name ...

Global site tag (gtag.js) - Google Analytics