• Ext create动态加载分析


    主要涉及到Ext.js Inventory.js ClassManager.js Class.js Loader.js Boot.js

    在ClasManager.js的Ext.create中

    Ext.syncRequire(name); // 加载类的js

    Loader.js 中

    syncRequire: function () {
                var wasEnabled = Loader.syncModeEnabled;
    
                Loader.syncModeEnabled = true;
    
                var ret = Loader.require.apply(Loader, arguments);
    
                Loader.syncModeEnabled = wasEnabled;
    
                return ret;
            },
     require: function (expressions, fn, scope, excludes) {
                if (excludes) {
                    return Loader.exclude(excludes).require(expressions, fn, scope);
                }
    
                var classNames = Manager.getNamesByExpression(expressions);
    
                return Loader.load(classNames, fn, scope);
            },
    load: function (classNames, callback, scope) {
                if (callback) {
                    if (callback.length) {
                        // If callback expects arguments, shim it with a function that will map
                        // the requires class(es) from the names we are given.
                        callback = Loader.makeLoadCallback(classNames, callback);
                    }
                    callback = callback.bind(scope || Ext.global);
                }
    
                var state = Manager.classState,
                    missingClassNames = [],
                    urls = [],
                    urlByClass = {},
                    numClasses = classNames.length,
                    url, className, i, numMissing;
                
                for (i = 0; i < numClasses; ++i) {
                    className = Manager.resolveName(classNames[i]);
                    
                    if (!Manager.isCreated(className)) {
                        missingClassNames.push(className);
                        
                        if (!state[className]) {
                            urlByClass[className] = Loader.getPath(className);
                            urls.push(urlByClass[className]);
                        }
                    }
                }
                
                // If the dynamic dependency feature is not being used, throw an error
                // if the dependencies are not defined
                numMissing = missingClassNames.length;
                
                if (numMissing) {
                    Loader.missingCount += numMissing;
                    
                    Manager.onCreated(function () {
                        if (callback) {
                            Ext.callback(callback, scope, arguments);
                        }
                        
                        Loader.checkReady();
                    }, Loader, missingClassNames);
    
                    if (!_config.enabled) {
                        Ext.raise("Ext.Loader is not enabled, so dependencies cannot be resolved dynamically. " +
                                 "Missing required class" + ((missingClassNames.length > 1) ? "es" : "") + 
                                 ": " + missingClassNames.join(', '));
                    }
    
                    if (urls.length) {
                        Loader.loadScripts({
                            url: urls,
                            // scope will be this options object so we can pass these along:
                            _classNames: missingClassNames,
                            _urlByClass: urlByClass
                        });
                    }
                    else {
                        // need to call checkReady here, as the _missingCoun
                        // may have transitioned from 0 to > 0, meaning we
                        // need to block ready
                        Loader.checkReady();
                    }
                }
                else {
                    if (callback) {
                        callback.call(scope);
                    }
                    
                    // need to call checkReady here, as the _missingCoun
                    // may have transitioned from 0 to > 0, meaning we
                    // need to block ready
                    Loader.checkReady();
                }
                
                if (Loader.syncModeEnabled) {
                    // Class may have been just loaded or was already loaded
                    if (numClasses === 1) {
                        return Manager.get(classNames[0]);
                    }
                }
    
                return Loader;
            },
    /**
             * This is an internal method that delegate content loading to the 
             * bootstrap layer.
             * @private
             * @param params
             */
            loadScripts: function(params) {
                var manifest = Ext.manifest,
                    loadOrder = manifest && manifest.loadOrder,
                    loadOrderMap = manifest && manifest.loadOrderMap,
                    options;
                
                ++Loader.scriptsLoading;
                
                // if the load order map hasn't been created, create it now 
                // and cache on the manifest
                if (loadOrder && !loadOrderMap) {
                    manifest.loadOrderMap = loadOrderMap = Boot.createLoadOrderMap(loadOrder);
                }
    
                // verify the loading state, as this may have transitioned us from
                // not loading to loading
                Loader.checkReady();
    
                options = Ext.apply({
                    loadOrder: loadOrder,
                    loadOrderMap: loadOrderMap,
                    charset: _config.scriptCharset,
                    success: Loader.onLoadSuccess,
                    failure: Loader.onLoadFailure,
                    sync: Loader.syncModeEnabled,
                    _classNames: []
                }, params);
    
                options.userScope = options.scope;
                options.scope = options;
    
                Boot.load(options);
            },

    在Boot.js中

    load: function (request) {
                    //<debug>
    //                 _debug("Boot.load called");
                    //</debug>
                    var request = new Request(request);
    
                    if (request.sync || Boot.syncMode) {
                        return Boot.loadSync(request);
                    }
    
                    // If there is a request in progress, we must
                    // queue this new request to be fired  when the current request completes.
                    if (Boot.currentRequest) {
                        //<debug>
    //                     _debug("current active request, suspending this request");
                        //</debug>
                        // trigger assignment of entries now to ensure that overlapping
                        // entries with currently running requests will synchronize state
                        // with this pending one as they complete
                        request.getEntries();
                        Boot.suspendedQueue.push(request);
                    } else {
                        Boot.currentRequest = request;
                        Boot.processRequest(request, false);
                    }
                    return Boot;
                },
     loadSync: function() {
                var me = this;
                me.fetch({
                    async: false,
                    complete: function (response) {
                        me.onContentLoaded(response);
                    }
                });
                me.evaluate();
                me.notifyRequests();
            },
            fetch: function (req) {
                var url = this.getLoadUrl(),
                    async = !!req.async,
                    complete = req.complete;
    
                Boot.fetch(url, complete, this, async);
            },

    最终网络通讯在这

    fetch: function(url, complete, scope, async) {
                    async = (async === undefined) ? !!complete : async;
    
                    var xhr = new XMLHttpRequest(),
                        result, status, content, exception = false,
                        readyStateChange = function () {
                            if (xhr && xhr.readyState == 4) {
                                status = (xhr.status === 1223) ? 204 :
                                    (xhr.status === 0 && ((self.location || {}).protocol === 'file:' ||
                                        (self.location || {}).protocol === 'ionp:')) ? 200 : xhr.status;
                                content = xhr.responseText;
                                result = {
                                    content: content,
                                    status: status,
                                    exception: exception
                                };
                                if (complete) {
                                    complete.call(scope, result);
                                }
                                xhr.onreadystatechange = emptyFn;
                                xhr = null;
                            }
                        };
    
                    if (async) {
                        xhr.onreadystatechange = readyStateChange;
                    }
    
                    try {
                        //<debug>
    //                     _debug("fetching " + url + " " + (async ? "async" : "sync"));
                        //</debug>
                        xhr.open('GET', url, async);
                        xhr.send(null);
                    } catch (err) {
                        exception = err;
                        readyStateChange();
                        return result;
                    }
    
                    if (!async) {
                        readyStateChange();
                    }
    
                    return result;
                },
    
                notifyAll: function(entry) {
                    entry.notifyRequests();
                }
            };
    complete函数定义在这
    onContentLoaded: function (response) {
                var me = this,
                    status = response.status,
                    content = response.content,
                    exception = response.exception,
                    url = this.getLoadUrl();
                me.loaded = true;
                if ((exception || status === 0) && !_environment.phantom) {
                    me.error =
                        //<debug>
                        ("Failed loading synchronously via XHR: '" + url +
                            "'. It's likely that the file is either being loaded from a " +
                            "different domain or from the local file system where cross " +
                            "origin requests are not allowed for security reasons. Try " +
                            "asynchronous loading instead.") ||
                        //</debug>
                        true;
                    me.evaluated = true;
                }
                else if ((status >= 200 && status < 300) || status === 304
                    || _environment.phantom
                    || (status === 0 && content.length > 0)
                    ) {
                    me.content = content;
                }
                else {
                    me.error =
                        //<debug>
                        ("Failed loading synchronously via XHR: '" + url +
                            "'. Please verify that the file exists. XHR status code: " +
                            status) ||
                        //</debug>
                        true;
                    me.evaluated = true;
                }
            },
    
    
    
     
  • 相关阅读:
    mac下用xattr命令来删除文件的扩展属性
    使用vue.js实现checkbox的全选和多个的删除功能
    正则表达式匹配任意字符(包括换行符)的写法
    jQuery Mobile动态刷新页面样式
    jquery mobile各类标签的refresh
    jQuery .attr()和.removeAttr()方法操作元素属性示例
    jquery mobile各类组件刷新方法
    Apache PDFbox开发指南之PDF文档读取
    日期字符串解析--SimpleDateFormat严格限制日期转换setLenient(false)
    hdu5032 Always Cook Mushroom
  • 原文地址:https://www.cnblogs.com/coolzdp/p/7468738.html
Copyright © 2020-2023  润新知