48

对 AngularJS 来说非常新,我猜我正在尝试做的术语是延迟加载。我查看了几个不同的博客,但没有找到一个完全使用 AngularJS 的完整工作解决方案。

我知道如果我将<script src="js/process1.js"></script>index.html 放入,一切正常,我正在尝试减少在初始加载时拉下的 js 数量。

由于脚本标签位于部分中,它永远不会被加载,因此永远不会创建 P1Ctrl。因此,目前,如果用户进入应用程序并且从未进入 process55,则即使从未使用过,用户仍然拥有 process55 的代码。

有没有办法在执行 process1 路由时加载文件并将在 process1.js 中创建的对象注入 main 中定义的应用程序?

索引.html:

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Large Angular App</title>
    <link rel="stylesheet" href="lib/foundation/css/foundation.min.css" />
</head>
<body ng-app="largeApp" ng-controller="LargeAppController">

    <div>
        <a href="#/home">Home</a> | <a href="#/process1">Process1</a>
    </div>
    <br/>
    <br/>
    <br/>

    <ng-view>Test</ng-view>


    <script type="text/javascript" src="lib/jquery/jquery.min.js"></script>
    <script type="text/javascript" src="lib/angular/angular.js"></script>
    <script type="text/javascript" src="lib/angular/angular-route.js"></script>
    <script type="text/javascript" src="js/main.js"></script>
</body>
</html>

js/main.js:

var app = angular.module("largeApp", ['ngRoute']);

var appCtrl = app.controller("LargeAppController", function(){});


app.config(function ($routeProvider, $controllerProvider) {
    // save references to the providers

    app.registerCtrl = $controllerProvider.register,

    $routeProvider.when('/', {templateUrl: 'partials/home.html'});
      //Thinking I need to set up a resolve to fire off a script loader to load js.
    $routeProvider.when('/process1', {templateUrl: 'partials/process1/process1.html'});
    $routeProvider.otherwise({redirectTo: '/'});
});

部分/home.html:

   <div>
    Home Page
   </div>

部分/process1.html:

<script type="text/javascript" src="js/process1/Process1Controller.js"></script>
Process 1 {{process1data}}

js/process1.js:

console.log("I made it here");

app.registerCtrl('Process1Controller',function($scope){
            $scope.process1data = "Hello!";
        }
]);
4

1 回答 1

21

要以简单的方式实现控制器的延迟加载,您必须执行以下操作:

保存$controllerProvider.register(这是将控制器添加到已引导的 AngularJS 应用程序中的唯一方法)到您的应用程序(main.js)中的变量:

var app = angular.module('app',["ngRoute"]);
app.config(['$routeProvider', '$controllerProvider',
    function($routeProvider, $controllerProvider) {
        // remember mentioned function for later use
        app.registerCtrl = $controllerProvider.register;
        //your routes
        $routeProvider.when('/', {templateUrl: 'partials/home.html'});
        $routeProvider.when('/process1', {templateUrl: 'partials/process1.html'});
        $routeProvider.otherwise({redirectTo: '/'});
    }
]);

进程1.html

<script src="js/process1.js"></script>
<div ng-controller="P1Ctrl">
    {{content}}
</div>

现在,在process1.js中,您使用我们的registerCtrl

app.registerCtrl('P1Ctrl', function($scope)
{
   $scope.content = '...'; 
});

index.html可能保持不变。检查您process1.js是否正在加载(只需console.log()在 的主体中使用 right process1.js,而不是在P1Ctrl控制器中)。如果不是,请在 Angular 之前包含 jQuery:

<script src="lib/jquery/jquery.js"></script>
<script src="lib/angular/angular.js"></script>

重要提示:此方法不适用于 angular 1.2.0-rc.2 和 1.2.0-rc.3,因为 jQuery 的这个小技巧不起作用。

对于更复杂(和更漂亮)的解决方案,将.js文件作为路由定义中的依赖项,请查看该文章: http: //ify.io/lazy-loading-in-angularjs/ - 它也适用于 rc.2 和 rc.3。这里是 plunk 实现描述的方法:http://plnkr.co/edit/ukWikO5TVDtQ1l9WlrGD

于 2013-10-17T19:46:09.857 回答