Динамическая загрузка содержимого (панелей) в окне просмотра Ext Js - PullRequest
5 голосов
/ 15 сентября 2010

Ну, в общем, я смотрю на эту проблему, у меня есть много компонентов с динамическими вещами, которые написаны на стороне сервера с помощью PHP.

В зависимости от пользователя мои компоненты будут меняться в зависимости от роли пользователя.

Так что мне нужно знать любые способы / примеры / информацию о том, как это сделать.

1 - Я использовал функцию загрузки, которую имеет EXTJS, но там четко сказано, что я не буду загружать скрипт только в виде простого текста.

2 - я использовал eval (), но немного испугался такого подхода, как этот пример компонента макета ящика (статический)

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(\'panel1\');">Panel 1</a>'
                        },
                        {
                            html: '<a href="#" onClick="requestContent(\'panel2\');">Panel 2</a>'
                        },
                        contentPanel

                ]
            })

и обновить содержимое макета с помощью js-файлов, записанных на сервере

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

любой другой способ сделать это, я не хочу делать миллион различных компонентов и загружать их ВСЕ во время входа в систему, как многие люди говорят

Ответы [ 3 ]

3 голосов
/ 16 сентября 2010

Чтобы ответить на ваши вопросы:

  1. Метод .load БУДЕТ загружать скрипт и оценивать его после завершения загрузки контента, однако для этого вам потребуется установить параметр scripts: true, например:
my_panel.load({
  url: 'url_to_load.php/hmt/html/asp...',
  params: {param1: param1value, param2: param2value...etc},
  nocache: true,
  timeout: 30,
  scripts: true
});
  1. Использование eval () - это нормально ... но, учитывая вышеописанную конфигурационную конфигурацию scripts: true, это выполняется для javascript в исходном файле, вам не нужно использовать это.

Надеюсь, это поможет

2 голосов
/ 16 сентября 2010

Что я понял из вашего вопроса, так это то, что вы ищете динамический загрузчик файлов JS с обработчиком обратного вызова, т.е. функция обратного вызова будет вызываться только после полной загрузки файла.Я также сталкивался с подобными проблемами при запуске и после многих поисков и исследований, я разработал следующий код, который обеспечивает абсолютную функциональность загрузки файлов Dynamic JS и CSS:

Class ScriptLoader: (Поместите его в отдельный файл и загрузите сначала)

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

Теперь его можно использовать следующим образом:

Для файлов CSSзагрузка:

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

То есть вам просто нужно указать путь к файлам css в массиве и передать этот массив функции loadCss () в качестве аргумента.Для файлов CSS обратного вызова не требуется.

Для загрузки файла JS:

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

В этом случае так же, как вы ввели CSSфайлы, здесь вам просто нужно поместить этот массив файлов JS в опции скриптов.Функция обратного вызова вызывается только тогда, когда все файлы JS загружены успешно.Кроме того, если в любом случае файлы JS уже загружены в браузер (т. Е. Этот код уже запущен один раз), тогда элемент управления автоматически перейдет к функции обратного вызова.

2 голосов
/ 15 сентября 2010

Вы можете загружать JavaScript динамически, используя что-то вроде как ниже - в сети есть сотни вариантов.Таким образом, вы избежите вызова AJAX и обработки ответа (и последующего eval).

var aHeadNode = document.getElementById('head')[0];
var aScript = document.createElement('script');
aScript.type = 'text/javascript';
aScript.src = "someFile.js";
aHeadNode.appendChild(oScript);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...