我的AngularJS应用程序中的控制器目前是这样编码的:
app.controller('appController',[
        '$state','$timeout','enumService','userService','utilityService',appController
    ]);

function appController(
    $scope,$state,$timeout,enumService,userService,utilityService
) {

    ...

}

我想开始做的是使用require.js来处理控制器的延迟加载.我知道我应该使用这样的东西:

require(["app"],function (app) {
     app.controller('appController',function appController(
         $scope,utilityService
     ) {

         ...

     });
});

有人可以向我解释一下app.controller如何获得对服务的引用?我需要在require.js方面做任何其他事情吗?我正在跟踪我正在编写appController的方式吗?

TL;博士;最后一个解决方案是在最后一节,或者看看 this plunk

懒惰加载$注射器

angular-requirejs-seed项目说明如何通过设置如下这样的懒惰功能轻松实现延迟加载:

define([],function() {
    return ['$scope','$http','myInjectable',function($scope,$http,myInjectable) {
        $scope.welcomeMessage = 'hey this is myctrl2.js!';

        // because this has happened async,we've missed the digest cycle
        $scope.$apply();
    }];
});

…然后实例化控制器,如下所示:

.controller('MyCtrl2',['$scope','$injector',$injector) {
    require(['controllers/myctrl2'],function(myctrl2) {
        $injector.invoke(myctrl2,this,{'$scope': $scope});
    });
...

请注意,延迟加载的函数不是控制器.这只是一个使用$inject调用的函数,它允许它访问实际控制器的$范围,并允许它访问在你的应用程序中加载的任何注入.

您可以将相同的技术应用于服务,工厂或指令.

懒惰加载警告

在大多数情况下,延迟加载可能是自毁的.如果您的目标是为用户提供一个快速的网站,那么懒惰加载每个控制器是一个坏主意.一旦建立了HTTP连接,大多数互联网连接允许大量数据在短时间内流过电线.延迟,但是可以是真正的杀手.这就是为什么大多数网站这些天使用连接和缩小来打包他们的JavaScript并减少网络请求的数量,而不是依赖于延迟请求数量的延迟加载.

考虑你的应用程序的架构.您将创建多少个可重复使用的指令?在各种应用程序之间共享多少代码,不适合延迟加载?对于许多应用程序,大部分代码将由常见的组件组成,使得延迟加载毫无意义.

延迟加载在应用程序中是非常明确和分开的部分.那些非常独特和独立的片段可以被认为是单独的应用程序.然而,即使在这种情况下,您可能会考虑实际创建单独的应用程序,而不是组合它们

BTW,require.js is still useful even if you’re not Lazy-loading

Even if you’re not lazy-loading,require.js is extremely useful for
dependency management
. Used in conjunction with the require.js
optimizer it’s an elegant way to keep track of dependencies and
compress+minify your app.

You can also use require.js to load dependencies for running Jasmine
unit tests which helps keep your components modular,and speeds up
your tests by just loading the dependencies that you need. For unit
testing,I create a separate main-test.js file which calls
require.config(...) to load app dependencies as well as
testing-specific dependencies.

延迟装载架构

具有角度的惰性载荷相当复杂,因为角度不是设计用于支撑惰性载荷.在本节中,我将尝试引导您探索如何强制角度来支持延迟加载.这不是一个完整的解决方案,但我希望介绍在构建这样的应用程序时要了解的重要概念.

我们从路由器开始,而不是我在第一部分提出的angular-requirejs-seed,它实际上比延迟加载在你的应用程序的路由器中更有意义.使用ui-router,我们可以这样实现lazy-load:

...
app.$controllerProvider = $controllerProvider;
var lazyPartialDeferred;

$stateProvider
  ...
  .state('lazy',{
    url: "/lazy",templateProvider: function() { return lazyPartialDeferred.promise; },controller: 'lazyCtrl',resolve: {
      load: function($q,$templateCache) {
        var lazyCtrlDeferred = $q.defer();
        lazyPartialDeferred = $q.defer();
        require(['lazy'],function (lazy) {
          lazyCtrlDeferred.resolve();
          lazyPartialDeferred.resolve($templateCache.get('lazy.html'));
        });
        return lazyCtrlDeferred.promise;
      }
    }
  });
...

我们在这里做的是推迟部分(lazy.html)和控制器(lazyCtrl)的实例化,直到我们的requirejs模块(lazy.js)被加载为止.另外,请注意,我们直接从$templateCache加载我们的view,partial,lazy.html.也就是说,当我们加载lazy.js时,部分本身就包含在lazy.js中.理论上,我们可以从lazy.js中单独加载lazy.html,但为了获得最佳性能,我们应该将部分文件编译成我们的js文件.

我们来看看lazy.js:

define(['angular','lazy-partials'],function (angular) {
  var app = angular.module('app');

  var lazyCtrl =  ['$scope','$compile','$templateCache',function ($scope,$compile,$templateCache) {
    $scope.data = 'my data';
  }];

  app.$controllerProvider.register('lazyCtrl',lazyCtrl);
});

请记住,上述代码代表未编译的lazy.js.在生产中,lazy-partials.js(在上面的第一行引用)实际上将被编译成同一个文件.

现在我们来看看lazy-partials.js:

// Imagine that this file was actually compiled with something like grunt-html2js
// So,what you actually started with was a bunch of .html files which were compiled into this one .js file...
define(['angular'],function (angular) {
  var $injector = angular.element(document).injector(),$templateCache = $injector.get('$templateCache');

  $templateCache.put('lazy.html','<p>This is lazy content! and <strong>{{data}}</strong> <a href="#">go back</a></p>');
});

再次,上述代码并不完全是这样的文件真正的样子. lazy-partials.js实际上将使用像grunt-html2js这样的构建工具插件从您的html文件自动生成.

现在,您可以在理论上使用迄今提出的方法构建整个应用程序.但是,这有点… janky.我们更喜欢在lazy.js中实例化一个新的模块,例如appLazy = angular.module(‘app.lazy’),然后实例化我们的控制器,指令,服务等,如appLazy.directive(…) .

然而,我们不能这样做的原因是因为所有这些东西都是在已经在lazy.js加载的时候已被调用的angular.bootstrap方法中初始化(并且提供给我们的应用程序).而且我们不能再重新调用angular.bootstrap(…).

BTW,internally angular is doing this to bootstrap modules:

06005

createInjector is an internal function to angular that loops through
all of the modules and registers all of their varIoUs building blocks.

In lazy.js,we called $controllerProvider.register(..) to
lazily register our controller. createInjector also triggers a
call to the same function when the app is bootstrapped. Here is a list
of varIoUs angular building blocks and the way in which they are
registered by angular:

06006

那么,有没有办法懒散地实例化模块?是的,you can register a module and it’s sub-modules by iterating through various nested properties of the module object (requires and _invokeQueue),这个操作在一个名为ocLazyLoad的lib中被简化了.

本节中提供的大部分代码可在this plunker.

(灵感来源未提及:Couch Potato,AngularAMD)

完整的懒惰加载解决方案:

[ocLazyLoad ui-router requirejs] – plunk

因为ui路由器允许我们延迟加载模板和控制器,所以我们可以使用它与ocLazyLoad一起在路由更改之间即时加载模块.这个例子构建了上一节的原理,但是通过使用ocLazyLoad,我们有一个解决方案,可以使我们的延迟加载模块的结构与非惰性加载的模块相同.

这里的关键是我们的app.config(..)块:

app.config(function($stateProvider,$locationProvider,$ocLazyLoadProvider) {
    var lazyDeferred;

    $ocLazyLoadProvider.config({
      loadedModules: ['app'],asyncLoader: require
    });

    $stateProvider
      ...
      .state('lazy',{
        url: "/lazy",templateProvider: function() { return lazyDeferred.promise; },resolve: {
          load: function($templateCache,$ocLazyLoad,$q) {
            lazyDeferred = $q.defer();
            return $ocLazyLoad.load({
              name: 'app.lazy',files: ['lazy']
            }).then(function() {
              lazyDeferred.resolve($templateCache.get('lazy.html'));
            });
          }
        }
      });
    ...

lazy.js现在看起来像这样:

define(['angular',function (angular) {
  var appLazy = angular.module('app.lazy',['app.lazy.partials']);

  appLazy.controller('lazyCtrl',$templateCache) {
    $scope.data = 'my data';
  });
});

请注意,这个文件在延迟加载方面已经不复存在了.您可以轻松地以非懒惰的方式加载该文件,并不会知道这个区别.同样的原则适用于lazy-partials.js:

// Imagine that this file was actually compiled with something like grunt-html2js
// So,function (angular) {
  angular.module('app.lazy.partials',[])
    .run(function($templateCache) {
      $templateCache.put('lazy.html','<p>This is lazy content! and <strong>{{data}}</strong> <a href="#">go back</a></p>');
    });
});

>>> check out the fully-functioning plunk< 部署 当涉及到部署,这个难题的最后一块是使用requirejs优化器来连接和最小化我们的js文件.理想情况下,我们希望优化器跳过已经包含在主应用程序中的依赖关系的连接(即:普通文件).为了完成这个,see this repo和build.js file.

一个更优雅的解决方案

我们可以通过为a very elegant solution添加一个ui路由器装饰器来改善以前的繁琐.

如何在我的AngularJS应用程序中添加require.js?的更多相关文章

  1. HTML5 播放 RTSP 视频的实例代码

    目前大多数网络摄像头都是通过 RTSP 协议传输视频流的,但是 HTML 并不标准支持 RTSP 流。本文重点给大家介绍HTML5 播放 RTSP 视频的实例代码,需要的朋友参考下吧

  2. 利用Node实现HTML5离线存储的方法

    这篇文章主要介绍了利用Node实现HTML5离线存储的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  3. 详解如何通过H5(浏览器/WebView/其他)唤起本地app

    这篇文章主要介绍了详解如何通过H5(浏览器/WebView/其他)唤起本地app的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  4. H5混合开发app如何升级的方法

    本篇文章主要介绍了H5混合开发app如何升级的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  5. AmazeUI 折叠面板的实现代码

    这篇文章主要介绍了AmazeUI 折叠面板的实例代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  6. HTML5手指下滑弹出负一屏阻止移动端浏览器内置下拉刷新功能的实现代码

    这篇文章主要介绍了HTML5手指下滑弹出负一屏阻止移动端浏览器内置下拉刷新功能的实现代码,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

  7. Html5 video标签视频的最佳实践

    这篇文章主要介绍了Html5 video标签视频的最佳实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  8. html5唤起app的方法

    这篇文章主要介绍了html5唤起app的方法的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  9. HTML5拍照和摄像机功能实战详解

    这篇文章主要介绍了HTML5拍照和摄像机功能实战详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  10. ios – 在没有iPhone6s或更新的情况下测试ARKit

    我在决定下载Xcode9之前.我想玩新的框架–ARKit.我知道要用ARKit运行app我需要一个带有A9芯片或更新版本的设备.不幸的是我有一个较旧的.我的问题是已经下载了新Xcode的人.在我的情况下有可能运行ARKit应用程序吗?那个或其他任何模拟器?任何想法或我将不得不购买新设备?解决方法任何iOS11设备都可以使用ARKit,但是具有高质量AR体验的全球跟踪功能需要使用A9或更高版本处理器的设备.使用iOS11测试版更新您的设备是必要的.

随机推荐

  1. Angular2 innerHtml删除样式

    我正在使用innerHtml并在我的cms中设置html,响应似乎没问题,如果我这样打印:{{poi.content}}它给了我正确的内容:``但是当我使用[innerHtml]=“poi.content”时,它会给我这个html:当我使用[innerHtml]时,有谁知道为什么它会剥离我的样式Angular2清理动态添加的HTML,样式,……

  2. 为Angular根组件/模块指定@Input()参数

    我有3个根组件,由根AppModule引导.你如何为其中一个组件指定@input()参数?也不由AppModalComponent获取:它是未定义的.据我所知,你不能将@input()传递给bootstraped组件.但您可以使用其他方法来做到这一点–将值作为属性传递.index.html:app.component.ts:

  3. angular-ui-bootstrap – 如何为angular ui-bootstrap tabs指令指定href参数

    我正在使用角度ui-bootstrap库,但我不知道如何为每个选项卡指定自定义href.在角度ui-bootstrap文档中,指定了一个可选参数select(),但我不知道如何使用它来自定义每个选项卡的链接另一种重新定义问题的方法是如何使用带有角度ui-bootstrap选项卡的路由我希望现在还不算太晚,但我今天遇到了同样的问题.你可以通过以下方式实现:1)在控制器中定义选项卡href:2)声明一个函数来改变控制器中的散列:3)使用以下标记:我不确定这是否是最好的方法,我很乐意听取别人的意见.

  4. 离子框架 – 标签内部的ng-click不起作用

    >为什么标签标签内的按钮不起作用?>但是标签外的按钮(登陆)工作正常,为什么?>请帮我解决这个问题.我需要在点击时做出回复按钮workingdemo解决方案就是不要为物品使用标签.而只是使用divHTML

  5. Angular 2:将值传递给路由数据解析

    我正在尝试编写一个DataResolver服务,允许Angular2路由器在初始化组件之前预加载数据.解析器需要调用不同的API端点来获取适合于正在加载的路由的数据.我正在构建一个通用解析器,而不是为我的许多组件中的每个组件设置一个解析器.因此,我想在路由定义中传递指向正确端点的自定义输入.例如,考虑以下路线:app.routes.ts在第一个实例中,解析器需要调用/path/to/resourc

  6. angularjs – 解释ngModel管道,解析器,格式化程序,viewChangeListeners和$watchers的顺序

    换句话说:如果在模型更新之前触发了“ng-change”,我可以理解,但是我很难理解在更新模型之后以及在完成填充更改之前触发函数绑定属性.如果您读到这里:祝贺并感谢您的耐心等待!

  7. 角度5模板形式检测形式有效性状态的变化

    为了拥有一个可以监听其包含的表单的有效性状态的变化的组件并执行某些组件的方法,是reactiveforms的方法吗?

  8. Angular 2 CSV文件下载

    我在springboot应用程序中有我的后端,从那里我返回一个.csv文件WheniamhittingtheURLinbrowsercsvfileisgettingdownloaded.现在我试图从我的角度2应用程序中点击此URL,代码是这样的:零件:服务:我正在下载文件,但它像ActuallyitshouldbeBook.csv请指导我缺少的东西.有一种解决方法,但您需要创建一个页面上的元

  9. angularjs – Angular UI-Grid:过滤后如何获取总项数

    提前致谢:)你应该避免使用jQuery并与API进行交互.首先需要在网格创建事件中保存对API的引用.您应该已经知道总行数.您可以使用以下命令获取可见/已过滤行数:要么您可以使用以下命令获取所选行的数量:

  10. angularjs – 迁移gulp进程以包含typescript

    或者我应该使用tsc作为我的主要构建工具,让它解决依赖关系,创建映射文件并制作捆绑包?

返回
顶部