【问题标题】:Dynamically add scripts to my app depending on conditional根据条件动态地将脚本添加到我的应用程序
【发布时间】:2019-07-01 12:04:13
【问题描述】:

我创建了一个plunker 来解决我的问题。

我有一个从登录页面开始的包含多个页面的应用程序。当我的应用程序首次加载时,它会加载 index.html,它运行我设置的名为 config.js 的脚本,然后重定向到 login.html。这只是管理我想在整个应用程序中使用的一些设置。

config.js 中,我已经设置了window.localStorage.setItem("use_minified",true),我想在login.html 中使用它来确定是否为我的应用程序使用缩小文件。

我看了几个问题,比如这个:

Dynamically add script tag with src that may include document.write

我已经尝试过(你会在我的 plunker 中看到)但我收到了错误:

未捕获的错误:[$injector:modulerr] 无法实例化模块 myApp 原因:错误:[$injector:nomod] 模块“myApp”不是 可用的!您要么拼错了模块名称,要么忘记加载它。 如果注册模块,请确保将依赖项指定为 第二个参数。

【问题讨论】:

  • 1) 你好,用你引用的文件更新你的 plunker。 2) 在 javascript 文件 (config.js) 中执行重定向 3) 添加对 angular.js 文件的引用@allan vargas

标签: javascript html angularjs ionic-framework


【解决方案1】:

您应该使用任何依赖项/模块加载器,例如 requirejs,以使您的依赖项加载在应用程序中更有条理。

要在 DOM 中动态加载脚本,可以使用这样的函数 -

var loadScript = function (url, callback) {
    var script = document.createElement("script");
    script.type = "text/javascript";

    if (script.readyState) {  //IE
        script.onreadystatechange = function () {
            if (script.readyState == "loaded" || script.readyState == "complete") {
                script.onreadystatechange = null;

                console.log(url + ' loaded successfully.');

                if ($.isFunction(callback)) {
                    callback();
                }
            }
        };
    } else {  //Others
        script.onload = function () {
            console.log(url + ' loaded successfully.');

            if ($.isFunction(callback)) {
                callback();
            }
        };
    }

    script.src = url;
    document.getElementsByTagName("head")[0].appendChild(script);
}

此函数应驻留在预先加载的任何脚本中(即 config.js)。如果不需要,可以避免使用第二个参数。它只是为您提供了一种在脚本加载后如果您需要做某事的便利。

这是使用您的 myApp 对脚本加载功能的演示调用 -

var myApp = angular.module('myApp', ['ionic','ionic-datepicker','ui.router','toaster','ngAnimate']);

myApp.run(function(){
  config.loadScript('yourScriptPath', null);
})
.config(function($stateProvider, $urlRouterProvider) {

    //==========================================================================//
    // Build the pages up for the application with their respective controllers //
    //==========================================================================//
    $stateProvider
    .state('login', {
        cache               : false,
        url                 : '/',
        controller          : "LoginController",
        templateUrl         : 'login.html'
    })
    .state('page1', {
        cache               : false,
        url                 : '/page1',
        controller          : "page1controller",
        templateUrl         : 'page1.html'
    })
    .state('page2', {
        cache               : false,
        url                 : '/page2',
        controller          : "page2controller",
        templateUrl         : 'page2.html'
    })
    .state('page3', {
        cache               : false,
        url                 : '/page3',
        controller          : "page3controller",
        templateUrl         : 'page3.html'
    });

    $urlRouterProvider.otherwise('/');
});

谢谢

【讨论】:

  • 我已将该函数添加到 config.js 并按照您在 app.js 中的示例方式运行它,但我收到了 config is not defined
  • 如果应用程序使用最少的基本代码运行,请检查您的 plunker。
  • 我已对其进行了更新以包含我引用的文件。
【解决方案2】:

我的回答:

我将index.html 保持不变,以便它调用config.js 并重定向到login.html

我将这些添加到我的config.js 文件中:

function init_scripts() {
    var jsDirectory = "js";
    var jsExtension = ".js";

    if (JSON.parse(window.localStorage.config).use_minified) {
        jsDirectory = "js_min";
        jsExtension = ".min.js";
    }

    loadScripts([
        "../lib/ionic/js/ionic.bundle.js",
        "../cordova.js",
        "https://cdnjs.cloudflare.com/ajax/libs/angularjs-toaster/1.1.0/toaster.min.js",
        "/lib/ionic-datepicker-fork-ionic1/dist/ionic-datepicker.bundle.min.js",
        "/" + jsDirectory + "/app" + jsExtension,
        "/" + jsDirectory + "/page1" + jsExtension,
        "/" + jsDirectory + "/page2" + jsExtension,
        "/" + jsDirectory + "/page3" + jsExtension

    ], null);
}

function loadScripts(array, callback) {
    var loader = function(src, handler) {
        var script = document.createElement("script");
        script.src = src;
        script.onload = script.onreadystatechange = function() {
            script.onreadystatechange = script.onload = null;
            handler();
        }
        var head = document.getElementsByTagName("head")[0];
        (head || document.body).appendChild(script);
    };

    (function run() {
        if (array.length != 0) {
            loader(array.shift(), run);
        } else {
            callback && callback();
        }
    })();
}

在我的login.html<head> 中,我删除了所有<script> 标记并替换它们:

<head>
   <script src="/js/config.js"></script>
   <!-- Functions found in config.js -->
   <script>
      init_scripts();
      init_stylesheets();
   </script>
</head>

这似乎运行得很好。我也为样式表做了类似的事情,你可以看到我调用了函数init_stylesheets();,它使用了相同的概念。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-11
    • 2018-08-13
    • 2021-02-25
    • 2011-11-05
    • 1970-01-01
    • 2021-10-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多