AngularJS - 基于路由动态加载外部JS

use*_*014 22 html javascript jquery angularjs

我是Angular的新手.我看了一些教程并阅读了一些文档.我现在开始弄脏手了.我正在尝试制作一个包含多个视图的简单单页移动应用程序和一个用于控制每个视图的下一个\ back按钮.我正在使用Angular Mobile UI库,但这应该不重要.

基本的模型如下:

<html>
    <head>
        <link rel="stylesheet" href="mobile-angular-ui/dist/css/mobile-angular-ui-base.min.css">
        <link rel="stylesheet" href="mobile-angular-ui/dist/css/mobile-angular-ui-desktop.min.css">

        <script src="js/angular/angular.min.js"></script>
        <script src="js/angular/angular-route.min.js"></script>
        <script src="mobile-angular-ui/dist/js/mobile-angular-ui.min.js"></script>

        <script src="app/app.js"></script>
        <script src="app/firstController.js"></script>
        <script src="app/secondController.js"></script>
        <script src="app/thirdController.js"></script>

    </head>

    <body ng-app="demo-app">
        <div ng-view></div>

        <div ng-controller="nextBackController" class="navbar navbar-app navbar-absolute-bottom">
            <div class="btn-group justified">
              <a href="#/" class="btn btn-navbar btn-icon-only"><i class="fa fa-home fa-navbar"></i></a>
              <a href="#/second" class="btn btn-navbar btn-icon-only"><i class="fa fa-list fa-navbar"></i></a>
            </div>
        </div>

    </body>


</html>
Run Code Online (Sandbox Code Playgroud)

App.js如下:

var app = angular.module('demo-app', [
  "ngRoute",
  "mobile-angular-ui"
]);

app.config(function($routeProvider) {
  $routeProvider.when('/', { controller: "firstController",
                             templateUrl: "views/first.html"});
  $routeProvider.when('/', { controller: "secondController",
                             templateUrl: "views/first.html"});
  $routeProvider.when('/', { controller: "thirdController",
                             templateUrl: "views/first.html"});
});

controllers = {};

controllers.nextBackController = function($scope, $rootScope) {
    //Simple controller for the next, back buttons so we just put it in app.js
};

app.controller(controllers);
Run Code Online (Sandbox Code Playgroud)

firstController.js将包含类似于:

controllers.firstController = function($scope) {
    //Do our logic here!!!
};
Run Code Online (Sandbox Code Playgroud)

问题是如果您注意到HTML页面的顶部我必须加载所有控制器.这是不可扩展的.我希望每个控制器都在它自己的JS文件中,而不必静态加载每个控制器,因为用户可能永远不需要该控制器.有没有办法在切换路由时动态加载实际的JS文件?或者我可以在我的"first.html","second.html"等顶部粘贴脚本标签.

Raj*_*ury 22

如果我理解正确,您需要为每个视图加载特定的脚本?我正在从个人项目中分享这个片段,该项目使用ocLazyLoader插件来按需加载模块.

var myApp = angular.module("myApp", [
"ui.router", 
"oc.lazyLoad",  
]); 
Run Code Online (Sandbox Code Playgroud)

然后在你的路由中你可以相应地加载动态JS/CSS文件,在这个例子中我加载了UI Select插件依赖项

myApp.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {

$stateProvider

  // State
    .state('demo', {
        url: "/demo.html",
        templateUrl: "views/demo.html",
        data: {pageTitle: 'demo page title'},
        controller: "GeneralController",
        resolve: {
            deps: ['$ocLazyLoad', function($ocLazyLoad) {
                return $ocLazyLoad.load([{
                    name: 'ui.select',
 // add UI select css / js for this state
                    files: [
                        'css/ui-select/select.min.css', 
                        'js/ui-select/select.min.js'
                    ] 
                }, {
                    name: 'myApp',
                    files: [
                        'js/controllers/GeneralController.js'
                    ] 
                }]);
            }]
        }
    })
Run Code Online (Sandbox Code Playgroud)

好吧,我希望这很有用..


Lee*_*rth 7

如果你熟悉Grunt:

https://github.com/ericclemmons/grunt-angular-templates

使用Grunt和上面的构建任务从所有视图创建一个.js.在视图目录中的所有html文件中包含监视任务侦听器.每当对任何部分视图进行更改时,都会创建一个"$ templateCache"条目,其中包含文件中的所有html以及用于对缓存进行别名的URL.您的路线将以相同的方式指向部分视图,但不需要存在html文件.只有带有模板的.js文件.这样做的好处在于它可以加载一次,并且可以在客户端进行整个会话.这减少了http呼叫,您的流量只能减少到Web服务呼叫.

这是来自github链接的模板示例,上面是:

angular.module('app').run(["$templateCache", function($templateCache) {
$templateCache.put("home.html",
// contents for home.html ...
);
...
$templateCache.put("src/app/templates/button.html",
// contents for button.html
);
}]);
Run Code Online (Sandbox Code Playgroud)

如果你不熟悉Grunt

看看这个.它对于自动化构建,缩小,连接,转换等非常有价值......

http://gruntjs.com/


Eva*_*wry 5

除非你的应用程序是MASSIVE,否则你应该真的避免单独提供小的js文件.这将显着减慢您的应用程序,即使您想要根据您的问题建议根据需要找出懒惰获取文件的方法.

一个更好的方法(以及AngularJS团队使用和建议的方式)是使用BUILD PROCESS(你应该使用grunt它)连接所有的javascript文件,并将它们作为单个app.js文件提供.这样,您可以根据需要使用尽可能多的小js文件维护有组织的代码库,但是将脚本提取减少到单个请求.


小智 1

我不确定它在标准 Angular 中是如何工作的,但是,您可以使用 Angular-UI-Router:

控制器根据需要实例化,当创建相应的作用域时,即当用户通过 URL 手动导航到某个状态时,$stateProvider 会将正确的模板加载到视图中,然后将控制器绑定到模板的作用域。

https://github.com/angular-ui/ui-router/wiki