是否可以从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工具在“脚本”部分“资源”下跟踪所有已加载的文件。