当前位置: 首页 > 面试题库 >

如何使用AngularJS延迟加载非Angular JavaScript文件?

孟浩慨
2023-03-14
问题内容

是否可以从Angular控制器加载普通的旧JS或AMD模块?我以前为此使用RequireJS。

我以前在相当大的项目上使用过AngularJS和RequireJS。我正在基于MEAN Stack种子的新项目中工作,并且不使用requireJS。

我不太清楚,但是Angular有一个用于加载模块的系统-我可以从我的angular控制器中加载特定的javascript吗?

有没有办法修改我的module()声明以包含其他常规javascript文件?

谢谢!

编辑:为了让我对自己的工作有所了解,我有一个页面可以编辑几种不同的形式。所有这些都作为“表单”保存到我的数据库中。根据表单的类型,不同的字典值将映射到不同子视图中的不同字段。我的某些表格有下拉菜单或输入列表。这些是不同的,但是有关“表单”的所有其他内容都是以通用方式处理的。

因此,我有一个可以处理许多不同形式的单一形式控制器,对此结果我感到非常满意。主要问题来自每个表单都有一组单独的数据,除非需要,否则我希望避免加载这些数据。

我可以通过检查驱动ng-include的下拉菜单(加载子表单)来检查我正在加载的表单。

在短期内,我刚刚加载了所有内容并在我的范围内创建了名称空间以进行区分。

例如$ scope.form1和$ scope.form2,用于特定于特定表单的数据/规则。我宁愿不加载不需要的js。

编辑2: http :
//jsfiddle.net/HB7LU/1320/

function MyCtrl($scope) {       
    $scope.doSomething = function()
    {
     //I'm used to wrapping with e.g require('jquery..... here, can I do the same thing with angular?   
        alert(" I need to run a jquery function here...");
        var xml = $(someblock);
    };
}

我已经把我所说的完全弄成小提琴了。我想根据控制器中的某些路径来加载任意JS,并且仅在需要它们时才加载。

基本上,我有一些较大的名称空间要根据所选的多个选项之一进行加载,而仅加载所有名称空间将非常昂贵。


问题答案:

好的,我注释了我的代码,以便它可以解释所有内容。如果您还有其他问题,请告诉我。这是解决问题的方法,您的意见中将进一步说明。现场演示在这里(单击)。

标记:

<!DOCTYPE html>
<html ng-app="myApp" ng-controller="myCtrl">
<head>
</head>
<body>

  <button ng-click="load()">Load Foo</button>
  <!-- I'm using this to bootstrap the lazy loaded script -->
  <section ng-repeat="item in loaded" lazy="item"></section>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.min.js"></script>  
<script src="script.js"></script>
</body>
</html>

JavaScript:

var app = angular.module('myApp', []);

app.controller('myCtrl', function($scope) {
  //array of things to load
  $scope.lazyThings = [
    {directive:'my-foo-directive', file:'foo.js'}  
  ];
  $scope.loaded = [];
  $scope.load = function() {
    var loadIndex = $scope.loaded.length;
    if ($scope.lazyThings[loadIndex]) {
      $scope.loaded.push($scope.lazyThings[loadIndex]);
    }
  }
});

app.factory('myService', function($http) {
  return {
    getJs: function(path) {

      return $http.get(path).then(function(response) {
        deferred.resolve(response.data);
      });

    }
  }
});

//this adds an attribute to kick off the directive 
//for whatever script was lazy loaded
app.directive('lazy', function($compile, $q, myService) {
  var directiveReturn = {
    restrict: 'A',
    scope: {
      lazy: '='
    },
    link: function(scope, element) {
      myService.getJs(scope.lazy.file).then(function(data) {
        return addScript(scope.lazy.file, data, scope);
      }).then(function() {
        var $span = angular.element('<span></span>').attr(scope.lazy.directive, '');
        $compile($span)(scope);
        element.append($span);
      });
    }
  }

  var scriptPromises = {};
  function addScript(file, js, scope) {
    if (!scriptPromises[file]) { //if this controller hasn't already been loaded
      var deferred = $q.defer();
      //cache promise)
      scriptPromises[file] = deferred.promise;

      //inject js into a script tag
      var script = document.createElement('script');
      script.src = 'data:text/javascript,' + encodeURI(js);
      script.onload = function() {
        //now the script is ready for use, resolve promise to add the script's directive element
        scope.$apply(deferred.resolve());
      };
      document.body.appendChild(script);
      return deferred.promise;
    }
    else { //this script has been loaded before
      return scriptPromises[loadFile]; //return the resolved promise from cache
    }
  }

  return directiveReturn;
});

app.directive('myFooDirective', function() {
  return {
    restrict: 'A',
    link: function(scope, element) {
      //put the logic from your lazy loaded "foo.js" script here
      element.text(foo.someFunction());
    }
  }
});

样本懒加载脚本:

var foo = {
  someFunction: function() {
    return 'I am data from a lazy loaded js function!';
  }
};

您可以采用多种方法来实现我在此处演示的概念。只要考虑一下您想如何使用它,并编写一些指令来执行它即可。Angular使大多数事情变得非常简单。

注意: 注入脚本标签是可选的-
但是我非常喜欢这样做,而不是直接执行脚本。使用script标签时,您将能够使用dev工具在“脚本”部分“资源”下跟踪所有已加载的文件。



 类似资料:
  • 问题内容: 感谢Dan Wahlin的精彩文章,我设法实现了Angular的控制器和服务的延迟加载。但是,似乎没有一种干净的方法来懒惰加载独立的模块。 为了更好地解释我的问题,假设我有一个没有RequireJS的应用,其结构如下: 这是在Plunker中带有RequireJS的示例应用程序:http ://plnkr.co/aiarzVpMJchYPjFRrkwn 问题的核心是Angular不允许

  • 本文向大家介绍AngularJS使用ocLazyLoad实现js延迟加载,包括了AngularJS使用ocLazyLoad实现js延迟加载的使用技巧和注意事项,需要的朋友参考一下 最近开发一个系统遇到了一个问题,用angular路由一个html片段,该片段需要使用一个js插件来实现一个富文本编辑器。关键问题在于必须要在片段加载后通过js与dom元素进行绑定。一开始想当然以为直接把js代码写在代码段

  • 问题内容: 我正在使用angularjs,并且希望能够在需要时加载指令,而不是在页面开始时加载所有指令。我正在尝试为最常用的插件创建指令。 这样,一个direct可以在最终编译html之前用于加载所有需要的指令。 如果该指令与其他指令一起在页面开始加载,则一切正常。但是,如果稍后加载“子”指令(在“父”中),则该指令无效。以下是“ parent”指令的compile字段中pre字段的代码。 使用y

  • 我正在使用slick.js构建一个旋转木马。但是,即使我将属性从更改为,在我滚动到该图像之前,图像仍然会被加载。我怀疑这是因为我的图像中有标记。我的问题是如何防止浏览器加载响应图像,或者如何正确地延迟加载响应图像。 这是我的img标签的样本

  • 本文向大家介绍Webpack 实现 AngularJS 的延迟加载,包括了Webpack 实现 AngularJS 的延迟加载的使用技巧和注意事项,需要的朋友参考一下 随着你的单页应用扩大,其下载时间也越来越长。这对提高用户体验不会有好处(提示:但用户体验正是我们开发单页应用的原因)。更多的代码意味着更大的文件,直到代码压缩已经不能满足你的需求,你唯一能为你的用户做的就是不要再让他一次性下载整个应

  • 描述 (Description) 延迟加载可应用于图像,背景图像和淡入效果,如下所述 - 对于图像 要在图像上使用延迟加载,请按照给定的步骤进行操作 - 使用data-src属性而不是src属性来指定图像源。 将类lazy添加到图像。 <div class = "page-content"> ... <img data-src = "image_path.jpg" class = "l