javascript - 使用 browserify 以 Angular 延迟加载组件

标签 javascript angularjs browserify

我正在概述一个基于 Angular 的相当复杂的应用程序的架构。所以我从 angular-seed 项目开始,它似乎是一个很好的起点。令我困扰的是, Angular 应用程序本质上涉及预先加载所有内容。对于脚本加载器,似乎没有一个干净的方法。

我来自 backbone.js 背景,直接使用 require.js 基于路由器回调进行延迟加载是很安静的。在 Angular route ,定义如下:

// Declare app level module which depends on views, and components
angular.module('myApp', [
  'ngRoute'
]).
config(['$routeProvider', function($routeProvider) {
  $routeProvider.when({templateURL:'../tmpl.html',controller:'view1Ctrl'})
.when({templateURL:'../tmpl.html',controller:'view1Ctrl'})
.otherwise({redirectTo: '/view1'});
}]);

现在,$routeProvider.when({templateURL:'../tmpl.html',controller:'view1Ctrl'}) 我想延迟加载 Controller 和模板。我很想使用类似的东西:

$routeProvider.when({templateURL:'../tmpl.html',controller:require('view1Ctrl'})

使用 browserify 但它似乎并不干净,甚至没有要求。我知道这个问题已经以某种方式被问过好几次了,但我还没有找到一个明确的答案。

我在这里的首选是使用 browserify,因为它支持浏览器中广受欢迎的 cjs 模块。

最佳答案

我不确定如何使用 Browserify 执行此操作,因为我自己从未尝试过,但我强烈建议您查看 ocLazyLoad .

作为一个独立的服务,它在加载文件(json、css、js、模板——你能想到的)并将其注入(inject)到你已经运行的 Angular 应用程序中时表现出色。

话虽如此,它甚至更好(imo)与路由器(默认的 Angular 路由器,或 ui-router)结合使用。

有一些“种子项目”展示了如何将 ocLazyLoad 与 SystemJS 结合使用。


但你甚至不需要那个。

如果你使用 ui-router、ui-router-extras 和 ocLazyLoad,你可以将这样的东西放在一起以实现延迟加载状态:

ma​​in.js

/** 
 * Inject the needed dependencies into our main module.
 */
var main = angular.module('main', [ 'ui.router', 'ct.ui.router.extras.future', 'oc.lazyLoad' ]);

/**
 * Define the lazy loaded states.
 */
main.constant('lazyLoadedStates', [
  {
    name: 'about',
    url:  '/about',
    type: 'lazy',
    src: [
      '/path/to/about.module.js',
      '/path/to/AboutController.js'
    ]
  }
]);

/**
 * Setup the behaviour for when we hit a futureState with the 'lazy'
 * type. 
 * 
 * 1. Setup a deferred object.
 * 2. Resolve the promise when every file defined in the futureState.src has been loaded.
 * 3. Return the promise.
 */
main.config(function ($futureStateProvider, lazyLoadedStates) {
  $futureStateProvider.stateFactory('lazy', function ($q, $ocLazyLoad, futureState) {
    var deferred = $q.defer();

    $ocLazyLoad.load(futureState.src).then(function () {
      deferred.resolve();
    });

    return deferred.promise;
  });

  lazyLoadedStates.forEach($futureStateProvider.futureState);
});

这就是“框架” - 现在您只需要继续添加更多模块,使用更多代码,并将真实状态定义与虚拟相匹配一个在 lazyLoadedStates 常量中。

about.module.js

/** 
 * Setup the _real_ '/about' state in this lazy loaded file.
 */
angular.module('about', []).config(function ($stateProvider) {
  $stateProvider.state('about', {
    url: '/about',
    controller: 'AboutController',
    template: 'some_template.html'
  });
});

AboutController.js

/** 
 * Register the AboutController in a lazy loaded file. This could be done in about.module.js aswell,
 * but we'll do it here to separate stuff and showcase loading of multiple files. 
 */
angular.module('about').controller('AboutController', function ($state) {
  console.log('Im on a lazy loaded state!', $state.current);
});

我希望这能让您大致了解如何在 Angular 中设置延迟加载状态。我还没有找到一个更简单的方法来做到这一点,但我确信那里有关于如何将 ui-router(或默认的 Angular 路由器)与其他一些“惰性加载器”耦合的文章。

文档链接:

关于javascript - 使用 browserify 以 Angular 延迟加载组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29814817/

相关文章:

javascript - 使用 Javascript 隐藏 iPhone 的键盘

javascript - 外部 Javascript 在 react.js 中不起作用

AngularJS : email or phone number validation

browserify - 使用 Browserify 保留原始源图

javascript - 访问函数内部调用事件的 JQuery 对象

javascript - 如何关闭 iframe?

javascript - scope.$watch 不会随哈希对象(关联数组)一起触发?

AngularJS ng-if 和范围

javascript - Browserify 不会使用日期行进行编译

javascript - AngularJS、Browserify 和模块加载