ExtJS:requires 的作用是什么?

20

我一直在尝试弄清楚Ext JS 4中的requires是做什么用的,但似乎找不到一个合理的答案。假设我有以下代码:

app.js

Ext.Loader.setConfig({
  enabled: true
});

Ext.Loader.setPath('Ext.ux', 'examples/ux');

Ext.application({
  name: 'Test',
  appFolder: 'app',
  controllers: ['TheController'],
  requires: ['Test.Utils', 'Test.Utils2'],  // I don't think this does anything... couldn't find this option for Ext.application
  launch: function() {
    Ext.create('Ext.Viewport', {
      layout: 'border',
      items: [{
        xtype: 'thegrid',
        region: 'center',
        title: 'blah!'
      }]
    });
  }
});

app/controller/TheController.js

Ext.define('Test.controller.TheController', {
  extend: 'Ext.app.Controller',
  models: ['TheModel'],
  stores: ['TheStore'],
  views: ['TheGrid'],
  init: function() {
  }
});

app/view/TheGrid.js

Ext.define('Test.view.TheGrid', {
  extend: 'Ext.grid.Panel',
  alias: 'widget.thegrid',
  requires: ['Test.store.TheStore'],
  store: 'TheStore',
  columns: [
    {header: 'Name', dataIndex: 'name'},
    {header: 'Phone', dataIndex: 'phone'},
    {header: 'Hello', dataIndex: 'hello'}
  ]
});

app/store/TheStore.js

Ext.define('Test.store.TheStore', {
  extend: 'Ext.data.Store',
  requires: ['Test.model.TheModel', 'Test.Utils'],
  model: 'Test.model.TheModel',
  data: [
    {name: 'keanu reeves', phone: '1800matrices', hello: Test.Utils.getText()},
    {name: 'james earl jones', phone: '1800starwar', hello: 'nothing here'},
    {name: 'barack obama', phone: '1800prsidnt', hello: 'hello world'}
  ]
});

app/model/TheModel.js

Ext.define('Test.model.TheModel', {
  extend: 'Ext.data.Model',
  fields: [
    {name: 'name', type: 'string'},
    {name: 'phone', type: 'string'},
    {name: 'hello', type: 'string'}
  ]
});

app/Utils.js

Ext.define('Test.Utils', {
  singleton: true,
  requires: ['Test.Utils2'],
  getText: function() {
    return Test.Utils2.hello + 'world';
  }
});

app/Utils2.js

Ext.define('Test.Utils2', {
  singleton: true,
  hello: 'hello'
});

我知道这是一个非常长的例子,但我需要确保我完全描绘出我的做法。Utils依赖于Utils2,因为它需要调用Utils2的hello变量。其余的代码是在设置网格和调用TheStore中的Utils.getText函数。Firebug在TheStore.js的第6行抛出一个“Test.Utils未定义”的错误,此时,Test.Utils显然不存在,但Test.Utils2存在。
我的问题是...为什么Utils2存在而Utils不存在?我认为requires会引入我所需的类,从而使我能够使用它们,但我想我错了。我已经阅读了Sencha文档和大量线程,但没有什么真正有意义的东西,并且它并没有真正解释这个例子。有人能在这里提供一些见解吗?我会感激不尽。
另外,我知道我在这里做了一些愚蠢的事情,但这只是一个例子,所以我不想合并全局Utils或根本不使用全局...我只是想弄清楚要求选项。
更新
由于Izhaki下面的答案,我想到了一些东西。如果我想在我正在定义的类中使用所需的类,我必须等待对象被创建(即使用initComponent),所以我的存储和网格代码改为:
Ext.define('Test.store.TheStore', {
  extend: 'Ext.data.Store',
  requires: ['Test.model.TheModel'],
  model: 'Test.model.TheModel'
});

app/view/TheGrid.js

Ext.define('Test.view.TheGrid', {
  extend: 'Ext.grid.Panel',
  alias: 'widget.thegrid',
  requires: ['Test.store.TheStore'],
  store: 'TheStore',
  columns: [
    {header: 'Name', dataIndex: 'name'},
    {header: 'Phone', dataIndex: 'phone'},
    {header: 'Hello', dataIndex: 'hello'}
  ],
  // This is the change that works
  initComponent: function() {
    this.callParent();
    this.store.loadData([
      {name: 'keanu reeves', phone: '1800matrices', hello: Test.Utils.getText()},
      {name: 'james earl jones', phone: '1800starwar', hello: 'nothing here'},
      {name: 'barack obama', phone: '1800prsidnt', hello: 'hello world'}
    ]);
  }
});

这个方法可行,但我的最后一个问题是...我是否必须在TheStore中拥有TheModel的要求,并且在TheGrid中拥有TheStore的要求?因为我可以在TheGrid中使用Test.Utils,但TheGrid并没有明确说明它需要Test.Utils。
此外,这个来自Sencha文档的例子让我更加困惑,因为在创建TheStore之前,我显然没有使用Test.Utils,但是这个例子似乎可以在不等待初始化(使用initComponent)的情况下使用Child类。
2个回答

14

实际上这并不是一个愚蠢的问题。

你可以把requires看作是一种告诉ExtJS的方式:

"当你构造这个类的对象时,请确保首先动态加载所需的脚本"。

关于这行代码,你是正确的。

requires: ['Test.Utils', 'Test.Utils2'],

不需要在 app.js 中使用,原因是应用程序已经有了:

controllers: ['TheController'],
这句话的意思是,你需要在 JavaScript 脚本中引用 TheController 所在的脚本(任何与模型、视图、控制器或存储相关的定义也意味着相关的脚本会被动态加载)。 TheController 包含:
requires: ['Test.model.TheModel', 'Test.Utils'],

这将动态加载它们 - 这就是为什么在app.js中不需要相同的requires

您收到Firebug抛出Test.Utils未定义的原因是,您给出了一个配置(hello),其中包含对尚未动态加载的对象的引用 - 直到构建TheStore之前,在范围内没有Test.Utils


我喜欢这个答案,但还有一些未解释的事情(请看我问题更新部分)。 - incutonez
关于你的第一个新问题:你实际上不需要在TheStore中要求TheModel(特别是当你将其作为模型配置中的一部分时,这与要求它相同,但你不会得到设置器和获取器)。在TheGrid中也不需要要求-正如你所说,控制器会处理所有这些。 - Izhaki
基本上,当应用程序启动时,它会动态加载并创建所有控制器的实例以及相应配置对象中引用的所有模型/视图/存储。完成此操作后,所有这些都进入作用域(包括视图xtypes)。 - Izhaki
你提供的文档示例完全没问题,getText 中的 Test.Util2 也是一样 - 对这些对象的调用在函数调用内部(而不是从配置对象引用),因此它们只需要在类被创建后加载,而不是在此之前。对 getText 或 giveBirth 的调用只能在对象被创建后发生,而对象的创建又是在所需内容被动态加载之后进行的。 - Izhaki
我认为这差不多就解决了。谢谢所有的解释! - incutonez

0
  1. 没有它,HasMany关系根本无法正常工作。

  2. 它可以帮助JSBuilder知道要包含哪些文件。例如,如果您的Viewport使用边框布局,则不会被正确地包括在内,您必须使用uses或requires来包含它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接