更改状态时延迟加载 Angular 组件脚本

2024-03-05

这个问题已经占用了最后一天左右的时间。

我一直在尝试让我的 AngularJS 应用程序延迟加载每个状态组件的脚本文件。我正在 Angular 中从事一个大型项目,并且index.html文件已经变成了100多个<script>标签,包括各种控制器、服务和库的 JS。它们中的大多数都很小,所以加载时间并不是一个巨大的问题(尽管可能是),但对我来说它从来没有看起来干净过。

也许是因为我已经习惯了 PHP 的自动加载器,或者只是被所有可以在编译时加载自己的依赖项的语言宠坏了。它只是不是模块化的,必须在应用程序的根文档中加载一些次要的、边缘状态的指令的脚本,或者对于该指令实际所属的模块,如果它被移动到另一个应用程序而没有加载脚本本身,则不加载脚本本身。<script>荣耀名单。

不管怎样,我正在开始一个新项目并希望保持它的简洁,但是以这种方式将组件加载到 Angular 中会带来许多挑战。其中许多问题已在文档或某些博客文章、SO 问题或其他问题中一次或多次得到解决,但我还没有看到一种与其他 Angular 组件干净集成的端到端解决方案。

  1. Angular 仅引导ng-app如果渲染页面时 Angular 和模块已经加载,则使用该指令。即使使用延迟加载启动应用程序也需要解决方法。
  2. 模块 API 的方法仅在应用程序引导之前起作用。在应用程序引导之后,但在定义它们的脚本实际加载之后(以及实际需要它们时),注册新的控制器、指令、过滤器或服务需要一种解决方法。
  3. 延迟加载脚本和调用基于 AJAX 的服务都需要调用回调,并且将服务调用的结果注入到状态控制器中需要这些服务实际存在,以便在状态转换开始时被调用。实际上INVOKING延迟加载的服务并在状态更改之前解决它......需要一种解决方法。
  4. 所有这些都需要以一种看起来不笨拙的方式组合在一起,并且可以轻松地在多个应用程序中重用,而无需每次都重新发明轮子。

我已经看到了#1 和#2 的答案。明显地,angular.bootstrap http://docs.angularjs.org/api/angular.bootstrap可用于在整个页面加载后启动模块,无需ng-app指示。引导后添加组件不太明显,但是保存对各种的引用$provider配置块中的服务可以解决问题 http://ify.io/lazy-loading-in-angularjs/, 覆盖moduleAPI更加无缝所以 http://www.bennadel.com/blog/2553-Loading-AngularJS-Components-After-Your-Application-Has-Been-Bootstrapped.htm。解决#3 并以满足#4 的方式完成这一切有点难以捉摸。

上面解决 #2 的示例适用于控制器和指令。添加服务变得有点复杂,异步的,延迟加载的,并且意味着将它们的数据提供给延迟加载的控制器,尤其如此。对于 Isitor 先生来说,他的代码确实适用于注册控制器作为概念证明,但代码的编写方式并不能轻松扩展到延迟加载脚本有意义的应用程序类型,即具有数十到数百个包含、依赖项和异步服务的更大的应用程序。

我将发布我想出的解决方案,但如果有人有改进它的建议,或者已经找到了一个显着且完全不同的更好方法,请随时添加它。


这是 Angular 模块的代码lazy,取决于ui.router模块。当它包含在模块的依赖项中时,将启用状态脚本的延迟加载功能。我提供了主要应用程序模块、一些惰性组件和我的示例index.html,出于演示目的进行了消毒。我正在使用Script.js https://github.com/ded/script.js库来实际处理脚本加载。

Angular-ui-router-lazy.js

/**
 * Defines an AngularJS module 'lazy' which depends on and extends the ui-router
 * module to lazy-load scripts specified in the 'scripts' attribute of a state
 * definition object.  This is accomplished by registering a $stateChangeStart
 * event listener with the $rootScope, interrupting the associated state change
 * to invoke the included $scriptService which returns a promise that restarts the
 * previous state transition upon resolution.  The promise resolves when the
 * extended Script.js script loader finishes loading and inserting a new <script>
 * tag into the DOM.
 *
 * Modules using 'lazy' to lazy-load controllers and services should call lazy.makeLazy
 * on themselves to update the module API to inject references for the various $providers 
 * as the original methods are only useful before bootstrapping, during configuration,
 * when references to the $providers are in scope.  lazy.makeLazy will overwrite the
 * module.config functions to save these references so they are available at runtime,
 * after module bootstrapping.
 * See http://ify.io/lazy-loading-in-angularjs/ for additional details on this concept
 *
 * Calls to $stateProvider.state should include a 'scripts' property in the object
 * parameter containing an object with properties 'controllers', 'directives', 'services',
 * 'factories', and 'js', each containing an array of URLs to JS files defining these
 * component types, with other miscelleneous scripts described in the 'js' array.
 * These scripts will all be loaded in parallel and executed in an undefined order
 * when a state transition to the specified state is started.  All scripts will have
 * been loaded and executed before the 'resolve' property's promises are deferred,
 * meaning services described in 'scripts' can be injected into functions in 'resolve'.
 */

 (function() {
    // Instantiate the module, include the ui.router module for state functionality
    var lazy = angular.module('lazy',['ui.router']);

    /**
     * Hacking Angular to save references to $providers during module configuration.
     * 
     * The $providers are necessary to register components, but they use a private injector
     * only available during bootstrap when running config blocks.  The methods attached to the
     * Vanilla AngularJS modules rely on the same config queue, they don't actually run after the
     * module is bootstrapped or save any references to the providers in this injector.
     * In makeLazy, these methods are overwritten with methods referencing the dependencies
     * injected at configuration through their run context.  This allows them to access the
     * $providers and run the appropriate methods on demand even after the module has been
     * bootstrapped and the $providers injector and its references are no longer available.
     *
     * @param module      An AngularJS module resulting from an angular.module call.
     * @returns module    The same module with the provider convenience methods updated
     * to include the DI $provider references in their run context and to execute the $provider
     * call immediately rather than adding calls to a queue that will never again be invoked.
     */
    lazy.makeLazy = function(module) {
      // The providers can be injected into 'config' function blocks, so define a new one
      module.config(function($compileProvider,$filterProvider,$controllerProvider,$provide) {
        /**
         * Factory method for generating functions to call the appropriate $provider's
         * registration function, registering a provider under a given name.
         * 
         * @param registrationMethod    $provider registration method to call
         * @returns function            A function(name,constructor) calling
         * registationMethod(name,constructor) with those parameters and returning the module.
         */
        var register = function(registrationMethod) {
          /**
           * Function calls registrationMethod against its parameters and returns the module.
           * Analogous to the original module.config methods but with the DI references already saved.
           *
           * @param name          Name of the provider to register
           * @param constructor   Constructor for the provider
           * @returns module      The AngularJS module owning the providers
           */
          return function(name,constructor) {
            // Register the provider
            registrationMethod(name,constructor);
            // Return the module
            return module;
          };
        };

        // Overwrite the old methods with DI referencing methods from the factory
        // @TODO: Should probably derive a LazyModule from a module prototype and return
        // that for the sake of not overwriting native AngularJS code, but the old methods
        // don't work after `bootstrap` so they're not necessary anymore anyway.
        module.directive = register($compileProvider.directive);
        module.filter = register($filterProvider.register);
        module.controller = register($controllerProvider.register);
        module.provider = register($provide.provider);
        module.service = register($provide.service);
        module.factory = register($provide.factory);
        module.value = register($provide.value);
        module.constant = register($provide.constant);
      });
      // Return the module
      return module;
    };

    /**
     * Define the lazy module's star $scriptService with methods for invoking
     * the extended Script.js script loader to load scripts by URL and return
     * promises to do so.  Promises require the $q service to be injected, and
     * promise resolutions will take place in the Script.js rather than Angular
     * scope, so $rootScope must be injected to $apply the promise resolution
     * to Angular's $digest cycles.
     */
    lazy.service('$scriptService',function($q,$rootScope) {
      /**
       * Loads a batch of scripts and returns a promise which will be resolved
       * when Script.js has finished loading them.
       *
       * @param url   A string URL to a single script or an array of string URLs
       * @returns promise   A promise which will be resolved by Script.js
       */
      this.load = function(url) {
        // Instantiate the promise
        var deferred = $q.defer();
        // Resolve and bail immediately if url === null
        if (url === null) { deferred.resolve(); return deferred.promise; }
        // Load the scripts
        $script(url,function() {
          // Resolve the promise on callback
          $rootScope.$apply(function() { deferred.resolve(); });
        });
        // Promise that the URLs will be loaded
        return deferred.promise;
      };

      /**
       * Convenience method for loading the scripts specified by a 'lazy'
       * ui-router state's 'scripts' property object.  Promises that all
       * scripts will be loaded.
       *
       * @param scripts   Object containing properties 'controllers', 'directives',
       * 'services', 'factories', and 'js', each containing an array of URLs to JS
       * files defining those components, with miscelleneous scripts in the 'js' array.
       * any of these properties can be left off of the object safely, but scripts
       * specified in any other object property will not be loaded.
       * @returns promise   A promise that all scripts will be loaded
       */
      this.loadState = function(scripts) {
        // If no scripts are given, instantiate, resolve, and return an easy promise
        if (scripts === null) { var d = $q.defer; d.resolve(); return d; }
        // Promise that all these promises will resolve
        return $q.all([
          this.load(scripts['directives'] || null),
          this.load(scripts['controllers'] || null),
          this.load(scripts['services'] || null),
          this.load(scripts['factories'] || null),

          this.load(scripts['js'] || null)
        ]);
      };
    });

    // Declare a run block for the module accessing $rootScope, $scriptService, and $state
    lazy.run(function($rootScope,$scriptService,$state) {
      // Register a $stateChangeStart event listener on $rootScope, get a script loader
      // for the $rootScope, $scriptService, and $state service.
      $rootScope.$on('$stateChangeStart',scriptLoaderFactory($scriptService,$state));
    });

    /**
     * Returns a two-state function for handing $stateChangeStart events.
     * In the first state, the handler will interrupt the event, preventing
     * the state transition, and invoke $scriptService.loadState on the object
     * stored in the state definition's 'script' property.  Upon the resolution
     * of the loadState call, the handler restarts a $stateChangeStart event
     * by invoking the same transition.  When the handler is called to handle
     * this second event for the original state transition, the handler is in its
     * second state which allows the event to continue and the state transition
     * to happen using the ui-router module's default functionality.
     *
     * @param $scriptService    Injected $scriptService instance for lazy-loading.
     * @param $state            Injected $state service instance for state transitions.
     */
    var scriptLoaderFactory = function($scriptService,$state) {
      // Initialize handler state
      var pending = false;
      // Return the defined handler
      return function(event,toState,toParams,fromState,fromParams) {
        // Check handler state, and change state
        if (pending = !pending) {   // If pending === false state
          // Interrupt state transition
          event.preventDefault();
          // Invoke $scriptService to load state's scripts
          $scriptService.loadState(toState.scripts)
            // When scripts are loaded, restart the same state transition
            .then(function() { $state.go(toState,toParams); });
        } else {  // If pending === true state
          // NOOP, 'ui-router' default event handlers take over
        }
      };
    };
  })();

/** End 'lazy' module */

索引.html

<!DOCTYPE html>
<html>
  <head>
    <title>Lazy App</title>
    <script type='text/javascript' src='libs/script.js'></script>
    <script type='text/javascript'>
      $script.queue(null,'libs/angular/angular.min.js','angular')
             .queue('angular','libs/angular/angular-ui-router.min.js','ui-router')
             .queue('ui-router','libs/angular/angular-ui-router-lazy.js','lazy')
             .queue('lazy',null,'libs-angular')

             .queue('libs-angular','lazyapp/lazyapp.module.js','lazyapp-module');

      $script.ready('lazyapp-module',function() { console.log('All Scripts Loaded.'); });
    </script>
  </head>

  <body>
    <div ui-view='mainView'></div>
  </body>
</html>

函数被黑脚本.js https://github.com/ded/script.js/因为我更喜欢语法

$script.queue = function(aQueueBehind,aUrl,aLabel) {
  if (aQueueBehind === null) { return $script((aUrl === null?[null]:aUrl),aLabel); }
  $script.ready(aQueueBehind,function() {
    if (aUrl !== null)
      $script(aUrl,aLabel);
    else
      $script.done(aLabel);
  });
  return $script;
}

懒惰的应用程序模块.js

(function() {
  var lazyApp = angular && angular.module('lazyApp ',['lazy']);
  lazyApp = angular.module('lazy').makeLazy(lazyApp);

  lazyApp.config(function($stateProvider) {

    $stateProvider.state({
      name: 'root',
      url: '',
      views: {
        'mainView': { templateUrl: '/lazyapp/views/mainview.html', controller: 'lazyAppController' }
      },
      scripts: {
        'directives': [ 'lazyapp/directives/lazyheader/src/lazyheader.js' ],
        'controllers': [ 'lazyapp/controllers/lazyappcontroller.js' ],
        'services': [ 'lazyapp/services/sectionservice.js' ]
      },
      resolve: {
        sections: function(sectionService) {
          return sectionService.getSections();
        }
      }
    });
  });

  angular.bootstrap(document,['lazyApp']);
})();

节服务.js

(function() {
  var lazyApp = angular.module('lazyApp');

  lazyApp.service('sectionService',function($q) {
    this.getSections = function() {
      var deferred = $q.defer();
      deferred.resolve({
        'home': {},
        'news': {},
        'events': {},
        'involved': {},
        'contacts': {},
        'links': {}
      });
      return deferred.promise;
    };
  });
})();

懒惰头.js

(function() {
  var lazyApp = angular.module('lazyApp ');

  lazyApp.directive('lazyHeader',function() {
    return {
      templateUrl: 'lazyapp/directives/lazyheader/templates/lazyheader-main.html',
      restrict: 'E'
    };
  });
})();

惰性应用控制器.js

(function() {
  var lazyApp = angular.module('lazyApp ');

  lazyApp.controller('lazyAppController',function(sections) {
    // @TODO: Control things.
    console.log(sections);
  });
})();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

更改状态时延迟加载 Angular 组件脚本 的相关文章

  • 使用selenium IDE提取部分文本并将其放入变量中

    有人可以告诉我应该使用哪个命令来使用 Selenium Ide 从文本中仅提取数字 694575 并将其放入变量中以供进一步使用 这是带有文本的 div div class loginBoxTitle Edit Exhibition Cen
  • 如何理解 Angular JS 中的控制台错误消息?有什么工具吗?

    我是 Angular JS 的新手 我的第一个问题是如何理解 Angular JS 中控制台的错误消息 我编写了这段用于匹配密码的代码片段 它在控制台上抛出错误 但它工作正常 它是有线的 我无法从这些控制台消息中理解任何内容 谁能指出我为什
  • 如何使用键盘和鼠标控制相机 - Three.js

    我在 WEB GL 中有一个带有 Three js 的 3D 环境 并且我曾经使用 Orbitcontrols js http codepen io nireno pen cAoGI http codepen io nireno pen c
  • Twisted 的 Deferred 和 JavaScript 中的 Promise 一样吗?

    我开始在一个需要异步编程的项目中使用 Twisted 并且文档非常好 所以我的问题是 Twisted 中的 Deferred 与 Javascript 中的 Promise 相同吗 如果不是 有什么区别 你的问题的答案是Yes and No
  • 计算Javascript中两次点击之间的时间

    我想用 javascript 计算属性的两次点击之间的时间 但我不知道如何 例如 a href click here a 如果用户单击多次 假设 5 秒内 我想显示警报 如果有帮助的话我正在使用 jQuery 我对 javascript 不
  • 在浏览器中语音聊天? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我们正在寻求建立一个小组 voice 使用服务器上的node js 在浏览器中聊天 这可能吗 如果您希望您的解决方案是基于服务器端和客
  • 当您只能访问模块变量时注入模块

    假设你有一个 var app angular module Mod1 现在您需要向该模块注入其他内容 但您无法更改该行 您只能访问app多变的 所以这行不通 对吧 var mod2 angular module mod2 factory m
  • 在 BIRT 中输入参数后更新数据集查询

    在 BIRT 报告设计中传递参数后 如何更改或更新数据集的查询 详细说明 我有一个如下所示的查询 WHERE 该参数标记可以保存不同的值 在用户输入参数后 它看起来像这样 例如 WHERE column name 1 or WHERE co
  • 将 jquery-mobile 与 Webpack 结合使用

    我正在尝试使用 webpack 加载 jquery mobile 但到目前为止还没有运气 我知道 jquery mobile 依赖于 jquery ui 而 jquery ui 又依赖于 jquery 如何在 Webpack 中设置这样的场
  • Flask wtf.quick_form 运行一些 javascript 并设置表单变量

    我正在创建博客文章 到目前为止已经使用普通的 html 表单完成了 我所做的一个有趣的想法是运行 javascript onclick 并使用页面中的额外数据在表单中设置一个隐藏变量 这很好地传递到服务器并通过 request form 获
  • 未捕获的引用错误:myFunction 未定义[重复]

    这个问题在这里已经有答案了 这到底是怎么回事 http jsfiddle net sVT54 http jsfiddle net sVT54
  • jQuery 选择器:为什么 $("#id").find("p") 比 $("#id p") 更快

    该页面的作者 http 24ways org 2011 your jquery now with less suck http 24ways org 2011 your jquery now with less suck断言 jQuery
  • 使用 jquery 将字符串数组转换为整数

    我正在尝试将 jquery 中的字符串数组转换为整数数组 这是我的尝试 var cdata data values split each cdata function i l l parseInt l 我认为在这种情况下你不需要使用 Jqu
  • 如何将 Browserify 与外部依赖项一起使用?

    我正在尝试慢慢地将 Browserify 引入我的网站 但我不想重写所有 js 也不希望 jquery 和其他库的重复实例与我的 Browserify 版本捆绑在一起 如果我构建将 jquery 列为外部依赖项的模块 那么如何将其指向我的全
  • 如何在网页上实现文件上传进度条?

    当用户将文件上传到我的网络应用程序时 我想显示比动画 gif 更有意义的内容 我还有哪些可能性 编辑 我正在使用 Net 但我不介意是否有人向我展示与平台无关的版本 如果您对这一切在客户端通常如何工作感兴趣 就是这样 所有解决方案都通过 J
  • 有关于 PHP 中的 V8JS 的文档吗?

    有没有关于V8JS的文档 我是否只需要标准 PHP 或一些扩展即可使用 V8JS 我将非常感谢有关 PHP 中的 V8JS 的任何信息 要求 PHP 5 3 3 和 V8 库和标头安装在正确的路径中 Install http www php
  • WebRTC:通道、轨道和流与 RTP SSRC 和 RTP 会话之间的关系

    来自 Mozilla 网站 https developer mozilla org en US docs Web API Media Streams API https developer mozilla org en US docs We
  • 从多维无穷大数组中删除数组元素

    我想删除一个特定元素 例如 我想删除元素id 76在下面的数组中 而且 数组可以无限地组合在一起 这里的问题是我无法刷新页面 因为我使用 Vue js 进行即时操作 如果我能做到这一点 我的下一个问题可能是如何在我现在想要的地方添加一个元素
  • ES6 模板文字的延迟执行

    我正在玩新的ES6 模板文字 http tc39wiki calculist org es6 template strings 我首先想到的是String format对于 JavaScript 所以我开始实现一个原型 String pro
  • Django 与谷歌图表

    我试图让谷歌图表显示在我的页面上 但我不知道如何将值从 django 视图传递到 javascript 以便我可以绘制图表 姜戈代码 array Year Sales Expenses 2004 1000 400 2005 1170 460

随机推荐

  • Scrapy 抓取 div 具有多个类?

    我正在尝试使用 产品 类来获取 div 问题是 一些具有 product 类的 div 也具有 product small 类 所以当我使用xpath div class product 它仅捕获具有一个类的 div 而不捕获多个类的 di
  • 使用 PowerShell 对文件进行 AES 加密

    我能够使用此脚本成功对文件进行 AES 加密here https gallery technet microsoft com EncryptDecrypt files use 65e7ae5d file 165403 14 使用 Windo
  • 通过 Python 更改 Konsole 标题

    如何更改 Python 中的 Konsole 标题 我找到了这段代码 gt gt gt import sys gt gt gt sys stdout write x1b 2 test x07 但它仅适用于 Gnome 终端 不适用于 Kon
  • 如何从 C# 执行批处理文件?

    解决方案见文末 我不认为这会很难 我有一个命令文件 da cmd 其中包含 copy b d 7zS sfx d config txt d files 7z d setup exe 但 C 的这些行不会执行它 Process Start d
  • 更改 pdf 和非 Google 文档(EDU 域)的 acl

    我在尝试从 Google Apps 脚本 Google Apps for Education 更改文件所有权时收到此错误 GDataServiceException您尚无法更改该项目的所有者 我们正在努力 相同的代码适用于 Google A
  • 如何在mysql中存储类型可以是数字、日期或字符串的数据

    我们正在开发一个监控系统 在我们的系统中 值是由运行在不同服务器上的代理报告的 报告的观察结果可以是如下值 一个数值 例如 CPU USAGE 55 表示 55 的 CPU 处于使用状态 使用 某些事件被解雇 例如 备份完成 状态 例如SQ
  • PHP 中 preg_replace() 的字符串的最大长度?

    我发现如果我尝试在很长的字符串上使用 preg replace PHP 会向我的浏览器返回一个空页面 而不显示错误消息 我能够在我的测试环境中重现这个错误 preg replace 可以处理的字符串的最大长度是多少 是否可以增加这个长度 对
  • Firestore 查询 - 一对多关系

    我将开发 Android 移动应用程序并使用 Firebase 作为后端 我是 NoSql Firestore 的新手 在我的应用程序中 用户有很多主题 一个主题有很多帖子 帖子有很多评论和一张图片 用户也有很多追随者 在这种情况下 我如何
  • C# 4.0:将动态转换为静态

    这是一个与我问的另一个问题相关的分支问题here https stackoverflow com questions 2783616 net 4 0 dynamic object used statically 我将其分开 因为这实际上是一
  • Visual Studio 第一次启动需要很长时间

    我在 Windows 7 64 位计算机 RAM 为 6 GB 上下载并安装了 Visual Studio 2013 Profession Trial 但是 当我第一次启动它时 它说 我们正在准备就绪 感谢您的耐心等待 它已经持续了大约一个
  • 无框架的 C++ GUI

    据我了解 没有办法让 C GUI 设计器将您的应用程序作为一个独立的可执行文件发布 所有 3rd 方框架都以 dll s 等形式添加依赖项 无论是 MFC Qt WTL wxWidgets GTK 这让我只剩下一种解决方案 使用 Win32
  • 为什么八进制序列 '\0101' 不等于十进制 65?

    考虑这个 C 程序 unsigned char c2 0101 printf c d n c2 c2 我相信输出应该是 A 65但实际输出是1 49 推理 字符常量中以 0 作为前缀 声明为八进制格式 而 101 的八进制值为 65 那么
  • 定时功能

    警告 这有点递归 我回答了这个问题 Python 如何获取列表中最长元素之前的所有元素 https stackoverflow com questions 8740018 pythonhow can i get all the elemen
  • YouTube 分析 API 行为空

    我知道这个问题以前已经被回答过 但我似乎有一个不同的问题 直到几天前 我对 YouTube 的查询从未出现过问题 然而现在 每次我查询任何视频上的数据时 实际视频数据行都会以单个空数组的形式返回 这是我的完整代码 coding utf 8
  • flutter sqlite 事务使用错误警告数据库已被锁定

    我正在开发一个使用 sqlite 和事务的移动应用程序 下面的代码是通过使用sqlite事务保存模型到多个数据库表来从用户那里获取订单信息 Future
  • 如何使用 npm install 和 webpack 来使用 normalize.css?

    我正在将 webpack 与 ReactJS 一起使用 并试图弄清楚如何在 npm 安装后使用 normalize css https necolas github io normalize css https necolas github
  • 如何使用注释将控制器定义为服务?

    这似乎是使用控制器作为服务的最快 最简单的方法 但我仍然缺少一个步骤 因为它不起作用 这是我的代码 控制器 服务 Test TestBundle Controller TestController php use Symfony Bundl
  • Psycopg2execute_values 以文本形式发送所有值

    我在 postgres 中有这张表 CREATE TABLE target a json b integer c text id integer CONSTRAINT id fkey FOREIGN KEY id REFERENCES pu
  • 在 drupal 7 中更改管理员密码

    我正在使用内置的 Drupal 7 用户模块 用户注册 忘记密码电子邮件等等 我忘记了我的管理员密码 我可以访问托管在 1and1 com 上的网站 也可以访问 mysql 是否可以通过 SQL 更改密码或电子邮件地址 以便我可以访问管理页
  • 更改状态时延迟加载 Angular 组件脚本

    这个问题已经占用了最后一天左右的时间 我一直在尝试让我的 AngularJS 应用程序延迟加载每个状态组件的脚本文件 我正在 Angular 中从事一个大型项目 并且index html文件已经变成了100多个