开发者

Loading content dynamically (panels) in an Ext Js Viewport

Well basically im looking on this problem, i have many components with dinamic stuff that is written in the server side with PHP.

Depending on the user my components will change, based on the role of the user.

So i need to know any ways/examples/info on how to do this.

1- I used the load function EXTJS has, but it clearly says i wont load script only plain text.

2- i used eval() but im a bit scared o this approach, like this example crate layout component (static)

var contentPanel = new Ext.Panel({
                frame: true,
                style: {marginTop: '10px'},
                height: 315,
                border: true,
                bodyBorder: false,
                layout: 'fit',
                id: 'contentPanel'
            });


            var mainPanel = new Ext.Panel({
                title: 'Panel Principal',
                id: 'mainPanel',
                border: true,
                frame: true,
                width: '50%',
                style: {margin: '50px auto 0 auto'},
                height: 400,
                renderTo: Ext.getBody(),
                items: [
                        {
                            html: '<a href="#" onClick="requestContent(\'pane开发者_如何学Gol1\');">Panel 1</a>'
                        },
                        {
                            html: '<a href="#" onClick="requestContent(\'panel2\');">Panel 2</a>'
                        },
                        contentPanel

                ]
            })

and update the content of the layout with js files written on the server

function receiveContent(options, success, response)
        {



            var respuesta = response.responseText;

            //console.log(respuesta);

            eval(respuesta);

            //console.log(options.url);

            url = options.url;

            url = url.substring(0,(url.search(/(\.)/)));

            var contenedor = Ext.getCmp('contentPanel');

            contenedor.removeAll();

            var contenido = Ext.getCmp(url);

            contenedor.add(contenido);
            contenedor.doLayout();
        }

        function requestContent(panel)
        {
            //panel es el nombre del archivo que quiero
            Ext.Ajax.request({
                url: panel+'.js',
                callback: receiveContent
            });
        }

any other way for this to be done, what i DONT want to do is making a million different components and load them ALL at login time like many people seem to say


To address your questions:

  1. The .load method WILL load script and evaluate it once the content has finished loading, however to accomplish this you will need to set the scripts:true option, an example may be:
my_panel.load({
  url: 'url_to_load.php/hmt/html/asp...',
  params: {param1: param1value, param2: param2value...etc},
  nocache: true,
  timeout: 30,
  scripts: true
});
  1. Using eval() is fine...but seeing as the scripts:true config option above accomplishes this for javascript in the source file, you shouldnt need to use this.

Hope this helps


You might load JavaScript dynamically using something like like below - there are a hundred variations on the web. In this way, you would avoid the AJAX call and handling the response (and subsequent eval).

var aHeadNode = document.getElementById('head')[0];
var aScript = document.createElement('script');
aScript.type = 'text/javascript';
aScript.src = "someFile.js";
aHeadNode.appendChild(oScript);


What I understood from your question is that, you are looking for dynamic JS file loader with a callback handler i.e. the callback function will be called only when the file is loaded fully. I also faced similar problems at start and after searching a lot and doing some research, I developed the following code, it provides absolute Dynamic JS and CSS file loading functionality :

Class ScriptLoader: (Put it in a separate file and load it at first)

ScriptLoader = function() {
    this.timeout = 30;
    this.scripts = [];
    this.disableCaching = false;
};

ScriptLoader.prototype = {

    processSuccess : function(response) {
        this.scripts[response.argument.url] = true;
        window.execScript ? window.execScript(response.responseText) : window
                .eval(response.responseText);
        if (response.argument.options.scripts.length == 0) {
        }
        if (typeof response.argument.callback == 'function') {
            response.argument.callback.call(response.argument.scope);
        }
    },

    processFailure : function(response) {
        Ext.MessageBox.show({
                    title : 'Application Error',
                    msg : 'Script library could not be loaded.',
                    closable : false,
                    icon : Ext.MessageBox.ERROR,
                    minWidth : 200
                });
        setTimeout(function() {
                    Ext.MessageBox.hide();
                }, 3000);
    },

    load : function(url, callback) {
        var cfg, callerScope;
        if (typeof url == 'object') { // must be config object
            cfg = url;
            url = cfg.url;
            callback = callback || cfg.callback;
            callerScope = cfg.scope;
            if (typeof cfg.timeout != 'undefined') {
                this.timeout = cfg.timeout;
            }
            if (typeof cfg.disableCaching != 'undefined') {
                this.disableCaching = cfg.disableCaching;
            }
        }

        if (this.scripts[url]) {
            if (typeof callback == 'function') {
                callback.call(callerScope || window);
            }
            return null;
        }

        Ext.Ajax.request({
                    url : url,
                    success : this.processSuccess,
                    failure : this.processFailure,
                    scope : this,
                    timeout : (this.timeout * 1000),
                    disableCaching : this.disableCaching,
                    argument : {
                        'url' : url,
                        'scope' : callerScope || window,
                        'callback' : callback,
                        'options' : cfg
                    }
                });

    }

};

ScriptLoaderMgr = function() {
    this.loader = new ScriptLoader();

    this.load = function(o) {
        if (!Ext.isArray(o.scripts)) {
            o.scripts = [o.scripts];
        }

        o.url = o.scripts.shift();

        if (o.scripts.length == 0) {
            this.loader.load(o);
        } else {
            o.scope = this;
            this.loader.load(o, function() {
                        this.load(o);
                    });
        }
    };

    this.loadCss = function(scripts) {
        var id = '';
        var file;

        if (!Ext.isArray(scripts)) {
            scripts = [scripts];
        }

        for (var i = 0; i < scripts.length; i++) {
            file = scripts[i];
            id = '' + Math.floor(Math.random() * 100);
            Ext.util.CSS.createStyleSheet('', id);
            Ext.util.CSS.swapStyleSheet(id, file);
        }
    };

    this.addAsScript = function(o) {
        var count = 0;
        var script;
        var files = o.scripts;
        if (!Ext.isArray(files)) {
            files = [files];
        }

        var head = document.getElementsByTagName('head')[0];

        Ext.each(files, function(file) {
                    script = document.createElement('script');
                    script.type = 'text/javascript';
                    if (Ext.isFunction(o.callback)) {
                        script.onload = function() {
                            count++;
                            if (count == files.length) {
                                o.callback.call();
                            }
                        }
                    }
                    script.src = file;
                    head.appendChild(script);
                });
    }
};

ScriptMgr = new ScriptLoaderMgr();

Now it can be used this way:

For CSS files loading :

ScriptMgr.loadCss([first.css', 'second.css']);

That is you just need to provide css files path in an array and pass that array to loadCss() function as an argument. No callback is required for CSS files.

For JS file loading :

ScriptMgr.load({
     scripts : ['lib/jquery-1.4.2.min.js','lib/jquery.touch-gallery-1.0.0.min.js'],
     callback : function() {              
          //Here you will do those staff needed after the files get loaded
     },
     scope : this
});

In this case, the same way you entered CSS files, here you just need to put that array of JS files in scripts option. The callback function is called only when all the JS files are loaded successfully. Also, if in any case, the JS files are already loaded in the browser (i.e. already this code is run once), then the control will automatically go to the callback function.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜