I had searched and read the ExtJS Doc. It says:

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
    }
});

but i try:

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

What's the difference when I set the uses property? Thanks!

有帮助吗?

解决方案

That's to avoid cyclic dependencies.

Consider the following example:

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!');
});

The alert will never fires. If you tries that with a dev build (eg. ext-all-dev.js), the loader will tell you why:

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

Replaces the requires with uses in any of the two classes, and problem solved, alert shooting.

To address the last part of your question, you should avoid using Ext.create completely... In part for performance reasons, but especially because in dev mode, while the dynamic Loader is enabled, you won't notice missing requires if you use it. And that may cost you some time to find all the missing one when you'll try to compile your app... While this will cause a crash you can't miss:

new My.Class();

其他提示

The Uses property is a list of optional classes to load together with this class. These aren't necessarily loaded before this class is created, but are guaranteed to be available before Ext.onReady listeners are invoked.

ExtJS Doc you cited

Uses is saying those classes ['Child'] need to be defined before this class 'Mother' is instantiated. The onReady function will defer to fire until the requires classes are defined but will fire if the uses classes aren't.

There are two ways to declare dependencies, the recommended way is to put them in the requires property:

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

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

In fact uses has one and only one purpose: to break circular dependencies.

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'],
    ...
});

Technically speaking, requires will guarantee that the dependencies are loaded before the class that depends on them is created; uses will only guarantee that the dependencies will be loaded before the onready event is fired, i.e. when everything has been loaded.

TL;DR You shouldn't be using uses at all. Use requires instead.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top