PDA

View Full Version : [CLOSED] Dynamically loaded classes cannot be extended



natedsaint
2 Jan 2013, 12:58 PM
Ext version tested:

Discovered in our app as Ext 4.1.3 (example in test case uses GPL, 4.1.0 for licensing reasons)
Browser versions tested against:

Chrome 23.0.1271.97 m
IE 9.0.8112.16421
FF17.0 (firebug 1.11.1 installed)
DOCTYPE tested against:

html5 (<!DOCTYPE html>)
Description:

Dynamically loaded classes cannot be extended as expected.
Steps to reproduce the problem:

Create a dynamically loaded class (in the test case, APP.test).
Extend that dynamically loaded class in this root file (in the test case, TestClass).
The result that was expected:

APP.test will be dynamically loaded.
TestClass will be instantiated based on that code.
The result that occurs instead:

APP.test appears to be dynamically loaded.
TestClass is undefined.
Test Case: (note that because of dynamic loading, you will need to run this on the server to verify the bug, hence why I have included a live test case url).



// main document
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<title>Sencha Test Case</title>
<script type="text/javascript" src="http://cdn.sencha.io/ext-4.1.0-gpl/ext-all.js"></script>
<script type="text/javascript">
Ext.Loader.setConfig({
enabled:true,
paths: {
'APP':'app',
}
});
Ext.define('TestClass',{extend:'APP.test'}); // will dynamically load, but TestClass is not created
try { // to avoid murdering the runtime, we'll throw it in a try
console.log(TestClass);
} catch(e) {
console.log("Error trying to log TestClass: ",e); // check your console, shows that TestClass is undefined
}
Ext.create('APP.test'); // instantiate the base class pulled in from the dynamically loaded code
Ext.define('TestClass',{extend:'APP.test'}); // extend that
console.log(TestClass); // shows as expected

// use a non-dynamically loaded class
Ext.define('TestClass2',{extend:'Ext.data.Model'});
console.log(TestClass2); // works as expected, didn't have to Ext.create a model first.
</script>
</head>
<body>
<div id="main">
View the source and check your console!
</div>
</body>
</html>

// dynamically loaded file, app/test.js

Ext.define('APP.test',{param:'value'});


See this URL for live test case:

http://ex.nathanstpierre.com/sencha/sencha_dynamic_loading_bug.html
Possible fix:

It appears define is getting short-circuited in the event of a dynamic load, but I'm not sure by what mechanism.
Additional CSS used:

none necessary in this example
Operating System:

Windows 7 / Ubuntu LTS 12.04 (Precise Pangolin)

evant
2 Jan 2013, 7:06 PM
Unless I'm mis-reading I don't think this is a bug.

When you define TestClass2, Ext.data.Model is already loaded since it's part of ext-all.js. As such, it can go ahead and define the class straight away and it can be used, since all of the dependencies are there.

When you define TestClass for the first time, the class it's extending is yet to be loaded. This loading is asynchronous, so the define can't finish until the dependencies are loaded. There is a callback you can use:



Ext.define('Foo', {
extend: 'Base'
}, function(){
console.log(this);
});


When you call .create(), it figures out that App.Test isn't loaded yet, so then it synchronously tries to load that class because it can't continue any further until all the dependencies are loaded. Then you define TestClass again, which, by this point, has all the dependencies loaded.

natedsaint
3 Jan 2013, 7:33 AM
Urgh! I figured it was something this simple, but our test case was muddied by something else:

We initially discovered this by carefully using asynchronous testing in Jasmine (waiting for the callback of the define before running the test on the new class) but there was an exception caused by another block of code that was causing this one to fail. I wrote a much more basic test and found the problem.

Thanks for the help!