Ext.define必须设置uses属性的情况是什么?

时间:2013-12-10 08:01:02

标签: extjs extjs4 extjs4.1 extjs4.2

我搜索并阅读了ExtJS Doc。它说:

Ext.define('Mother', {
    uses: ['Child'],
    giveBirth: function() {
        // This code might, or might not work:
        // return new Child();

        // Instead use Ext.create() to load the class at the spot if not loaded already:
        return Ext.create('Child'); // will find and load the Child.js file
    }
});

但我尝试:

Ext.define('Mother', {
    giveBirth: function() {
        return Ext.create('Child'); // will find and load the Child.js file, too
    }
});

设置uses属性有什么区别? 谢谢!

3 个答案:

答案 0 :(得分:3)

Uses属性是要与此类一起加载的可选类的列表。这些不一定在创建此类之前加载,但保证在调用Ext.onReady侦听器之前可用。

ExtJS Doc you cited

Uses表示在实例化此类['Child']之前需要定义这些类'Mother'onReady函数将在定义requires类之前推迟,但如果uses类不是,则会触发。

答案 1 :(得分:3)

声明依赖关系的方法有两种,推荐的方法是将它们放在requires属性中:

Ext.define('Foo', {
    requires: ['Bar'],

    getBar: function() {
        // Bar class is guaranteed to be loaded
        return new Bar();
    }
});

实际上uses只有一个目的:打破循环依赖。

Ext.define('Foo', {
    requires: ['Bar'],
    ...
});

Ext.define('Bar', {
    // Can't use requires here, as this would create a deadlock
    // OTOH we should let the Loader know that Bar depends
    // on Foo, so that Foo would be loaded too, eventually
    uses: ['Foo'],
    ...
});

从技术上讲,requires将保证在创建依赖于它们的类之前加载依赖项; uses只会保证在onready事件被触发之前加载依赖项,即一切都已加载。

TL; DR您根本不应该使用uses。请改用requires

答案 2 :(得分:3)

这是为了避免循环依赖。

考虑以下示例:

src/Foo.js

Ext.define('Test.Bar', {
    requires: 'Test.Foo'
}, function() {
    console.log('Loaded Bar');
});

src/Bar.js

Ext.define('Test.Foo', {
    requires: 'Test.Bar'
}, function() {
    console.log('Loaded Foo');
});

app.js

Ext.Loader.setConfig({
    enabled: true
    ,paths: {
        Test: 'src'
    }
});

Ext.require('Test.Foo');

Ext.onReady(function() {
    alert('Everything\'s loaded!');
});

警报永远不会触发。如果你尝试使用dev build(例如ext-all-dev.js),加载器会告诉你原因:

> Uncaught Error: Deadlock detected while loading dependencies! 'Test.Foo' and 'Test.Bar' mutually require each other. Path: Test.Foo -> Test.Bar -> Test.Foo

在两个类中的任何一个中用requires替换uses,问题解决,警报拍摄。

要解决问题的最后部分,您应该避免完全使用Ext.create ...部分原因是出于性能原因,但特别是因为在开发模式下,启用动态加载程序时,您将不会注意到如果您使用它,则会丢失requires。当你试图编译你的应用程序时,这可能会花费你一些时间找到所有缺失的...虽然这会导致崩溃,你不能错过:

new My.Class();