PDA

View Full Version : Fiddle not loading user-defined classes



jinsley
25 Nov 2013, 5:34 AM
https://fiddle.sencha.com/#fiddle/1pj

This fiddle is not loading the classes in the MyApp folder as configured. Not sure why as it seems fairly basic.

Any ideas?

mitchellsimoens
25 Nov 2013, 6:13 AM
The file at MyApp/mixin/MyFeature.js has a class of MyApp.view.Base in it.

The filesystem is a fake one, the classes will just get dumped into the generated HTML that gets written to the iframe and therefore if you use the requires in the class there is no guarantee that the class will be defined.

jinsley
25 Nov 2013, 7:12 AM
Thanks for the quick reply. Almost working now...

jinsley
25 Nov 2013, 7:42 AM
Not sure why it tries to load MyApp.controller.Main - is it because of the controllers: ['Main'] in app.js ?

RoyW
4 Dec 2013, 7:49 AM
First I would like to say I really like Sencha Fiddle and I think you are doing a great job.

This thread interested me because I have managed to create a fiddle with multiple files that worked so was intrigued as to wht this was not working.

The clue was

the classes will just get dumped into the generated HTML
I cloned the original project here
https://fiddle.sencha.com/#fiddle/1to

I was then able to look at the generated code which looks like this



/*
* This is the important part of the Fiddle - load the ajax simulator and/or run
* the fiddle code.
*/
function doFiddleStuff() {

Ext.Loader && Ext.Loader.setPath && Ext.Loader.setPath({
'Ext.ux' : 'https://extjs.cachefly.net/ext/gpl/4.2.1/examples/ux'
});






/*
* Application
* ----------------------------------------------------------------------
*/

Ext.application({

name: 'MyApp',
appFolder: 'MyApp',

autoCreateViewport: true,

controllers: [
'Main'
]

});






/*
* ----------------------------------------------------------------------
*/
Ext.define('MyApp.controller.Main', {
extend: 'Ext.app.Controller',
stores: [
'TestData'
]
});




/*
* ----------------------------------------------------------------------
*/
Ext.define('MyApp.mixin.MyFeature', {

init: function () {
this.valTables = {};
var keyNames = this.getClassNames();
Ext.Array.every(keyNames, this.loadValTables, this);
},

getVal: function (str) {
return this.getString(str);
},

loadValTables: function (keyName) {

if (!this.valTables[keyName]) {
this.valTables[keyName] = keyName;
}
return true;
},

getClassNames: function () {

var classNames = [],
className,
theClass = this;

className = Ext.getClassName(theClass);

if (className && className.length > 0) {
classNames.push(className);
}

while ('superclass' in theClass) {
theClass = theClass.superclass;
className = Ext.getClassName(theClass);

if (className.match(/^Ext\./)) {
break;
}

if (className && className.length > 0) {
classNames.push(className);
}
}

return classNames;
},

getString: function (str) {

var value = str,
name,
val;

for (name in this.valTables) {
val = this.valTables[name];

if (val) {
value = val;
}
}
return value;
}
});



/*
* ----------------------------------------------------------------------
*/
Ext.define('MyApp.model.TestModel', {
extend: 'Ext.data.Model',
fields: ['id', 'value']
});



/*
* ----------------------------------------------------------------------
*/
Ext.define('MyApp.store.TestData', {
extend: 'Ext.data.Store',
model: 'MyApp.model.TestModel',
proxy: {
type: 'memory',
reader: {
'type': 'json'
}
},
data: [
{
'id': '1',
'value': 'test-val 1'
},
{
'id': '2',
'value': 'test-val 2'
},
{
'id': '3',
'value': 'test-val 3'
}
],
autoLoad: true
});



/*
* ----------------------------------------------------------------------
*/
Ext.define('MyApp.template.DataList', {

singleton: true,

mixins: {
mymixin: 'MyApp.mixin.MyFeature'
},

constructor: function () {
var self = this;
this.listTpl = Ext.create('Ext.XTemplate', [
'<tpl for=".">',
'<div>',
'{[this.getValue(values.value)]}',
'<\/div>',
'<\/tpl>',

{
getValue: function (data) {
return self.getVal("default val - ") + data;
}
}
]);

this.init();
this.callParent(arguments);
}
});



/*
* ----------------------------------------------------------------------
*/
Ext.define('MyApp.view.Container', {
extend: 'Ext.container.Container',
mixins: {
mymixin: 'MyApp.mixin.MyFeature'
},
//alias: 'widget.container',

constructor: function() {
this.init();
this.callParent(arguments);
}
});



/*
* ----------------------------------------------------------------------
*/
Ext.define('MyApp.view.DataView', {
extend: 'MyApp.view.View',
requires: [
//'MyApp.template.DataList'
],
store: 'TestData',
itemSelector: 'div',
alias: 'widget.myappdataview',
constructor: function () {
this.tpl = MyApp.template.DataList.listTpl;
this.callParent(arguments);
}
});



/*
* ----------------------------------------------------------------------
*/
Ext.define('MyApp.view.Main', {
extend: 'MyApp.view.Container',
requires: [
'Ext.tab.Panel',
'Ext.layout.container.Border',
'MyApp.view.DataView'
],

xtype: 'app-main',

layout: {
type: 'border'
},

initComponent: function () {
this.items = [
{
region: 'west',
xtype: 'panel',
title: this.getVal('default title'),
width: 150
},
{
region: 'center',
xtype: 'tabpanel',
activeTab: 0,
items: [
{
title: this.getVal('default title 2'),
items: [
{
xtype: 'myappdataview'
}
]
}
]
}
];
this.callParent(arguments);
}
});



/*
* ----------------------------------------------------------------------
*/
Ext.define('MyApp.view.View', {
extend: 'Ext.view.View',
mixins: {
mymixin: 'MyApp.mixin.MyFeature'
},
//alias: 'widget.dataview',

constructor: function () {
this.init();
this.callParent(arguments);
}
});



/*
* ----------------------------------------------------------------------
*/
Ext.define('MyApp.view.Viewport', {
extend: 'Ext.container.Viewport',
requires:[
'Ext.layout.container.Fit',
'MyApp.view.Main'
],

layout: {
type: 'fit'
},

items: [{
xtype: 'app-main'
}]
});



}


var Ext = Ext || {};

/*
* If the framework support pauseReady, we can work around IE issues with
* document.write of script tag by pushing most of the work into the low-level
* _beforereadyhandler hook which is called as soon as the Loader comes up.
* Then pushing out one more step to wait for the rest of the core framework
* to boot (just past Observable anyway). Once we reach that point we can add
* the rest of the JS assets and hook isReadyPaused to hold up the load for
* the analyzer hook ups.
*/
Ext._beforereadyhandler = function () {
Ext.define('fiddle.hack', {
override: 'Ext.util.Observable'
},
function () {



Ext.Loader.loadScript({
url: "https://extjs.cachefly.net/ext/gpl/4.2.1/packages/ext-theme-neptune/build/ext-theme-neptune-debug.js"
});


Ext.EventManager.isReadyPaused = function () {
return !Ext._continueFireReady;
};

Ext.onReady(doFiddleStuff);
});
};


This shows that the file is not generated in the 'dependency' order (like Sencha Cmd might do)

It seems to do MVC (at the moment) you have to put all you code in app.js.

I came up with the following template


/*
* --- mixins ----
*/

/*
* --- models ----
*/

/*
* --- stores ----
*/

/*
* --- views ----
*/

/*
* --- controllers ----
*/

/*
* --- application ----
*/

And then re-arranged the original fiddle to create this
1ub

mitchellsimoens
4 Dec 2013, 7:54 AM
I just created a simple fiddle that has a single controller in a separate file: https://fiddle.sencha.com/#fiddle/1uc

app.js is added after the controller, app.js should always be loaded after other files.

RoyW
4 Dec 2013, 7:55 AM
I forgot to mention: I also noticed that if you define a base class and extend it, it looks like the dependency order is also not honored. I saw that in the code the super class was being defined and was trying to extend the base class but that base class was defined further down in the generated code.

It looks like it would be a difficult task to ensure the generated file is in the correct order. (Maybe you can steal some code from Sencha Cmd :) )

mitchellsimoens
4 Dec 2013, 8:02 AM
I forgot to mention: I also noticed that if you define a base class and extend it, it looks like the dependency order is also not honored. I saw that in the code the super class was being defined and was trying to extend the base class but that base class was defined further down in the generated code.

It looks like it would be a difficult task to ensure the generated file is in the correct order. (Maybe you can steal some code from Sencha Cmd :) )

Like I said, the classes are dumped into the generated HTML. The order is the same order found in the tree as I just cascade through the tree store.

Cmd is built in Java so it would be porting things but likely that would not be too fruitful of a mission. Writing from scratch is a better course.

RoyW
4 Dec 2013, 8:09 AM
The order is the same order found in the tree as I just cascade through the tree store.

Aha, looking at the generated code from the original post I can see that now.

So, do you agree the generated code needs o be created in the dependency order and not the order they are in the tree?

Is there any code from Ext.loader that could be of use?

mitchellsimoens
4 Dec 2013, 8:35 AM
To be honest, it could be as easy as adding functionality to suspend Ext.Loader and resuming after the classes are defined.

RoyW
4 Dec 2013, 8:47 AM
Unfortunately I don't think so.

The files seem to be created in alphabetical order so the following wont work

File: MyApp/view/View.js


Ext.define('MyApp.view.View', {
extend: 'Ext.view.View',
...
});


File: MyApp/view/DataView.js


Ext.define('MyApp.view.DataView', {
extend: 'MyApp.view.View',
....
});



In the folder list 'DataView' appears alphabetically before 'View' so the code will be generated as follows


Ext.define('MyApp.view.DataView', {
extend: 'MyApp.view.View',
....
});
Ext.define('MyApp.view.View', {
extend: 'Ext.view.View',
...
});


As soo an Ext sees the " extend: 'Ext.view.View', " the loader will look for that class. It is not defined so will try to load it and fail. If the loader is disabled it will fail saying "MyApp.view.View is not defined"

mitchellsimoens
5 Dec 2013, 9:31 AM
So playing around with this code:


Ext.define('ClassB', {
extend : 'ClassA'
});

Ext.define('ClassA', {});

and of course it will try to load ClassA.js. Until I can work on a more robust solution, in Fiddle 1.1 I've come up with a way to pause and resume Ext.Loader and will insert Ext.Loader.pause() and Ext.Loader.resume() in the code automatically so there won't be anything you have to do, Fiddle will automatically insert this. Do note, the pause and resume aren't methods of Ext.Loader, Fiddle will be adding these methods.

ypandey
21 Jun 2014, 11:01 PM
Like I said, the classes are dumped into the generated HTML. The order is the same order found in the tree as I just cascade through the tree store.
Cmd is built in Java so it would be porting things but likely that would not be too fruitful of a mission. Writing from scratch is a better course.

Changing order of files fixes my issue. But every time i open fiddle again, the order reverts back.

If loading of files is based on tree sequence (which is very problematic) Shouldn't fiddle also save updated sequence of the tree structure?

https://fiddle.sencha.com/#fiddle/6st