简体   繁体   English

使用browserify以角度延迟加载组件

[英]lazy loading of components in angular with browserify

I am in process of outlining a architecture of a fairly complex application based on angular. 我正在概述基于角度的相当复杂的应用程序的体系结构。 So I started with the angular-seed project and it seems to be a good starting point. 所以我开始使用角度种子项目,这似乎是一个很好的起点。 What bothers me is that angular apps by nature involves loading everything upfront. 困扰我的是,角度应用程序本质上涉及到前期加载所有内容。 With script loaders, there doesn't seems to be a clean way around. 使用脚本加载器,似乎没有一个干净的方法。

I came from a backbone.js background and there it was quiet straight to use the require.js for lazy loading based on the router callbacks. 我来自backbone.js背景,在那里它很安静直接使用require.js进行基于路由器回调的延迟加载。 In angular routes are somewhat defined like the below: 角度路线在某种程度上定义如下:

// 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'});
}]);

now here, $routeProvider.when({templateURL:'../tmpl.html',controller:'view1Ctrl'}) I would like to lazily load the controller and the template. 现在这里, $routeProvider.when({templateURL:'../tmpl.html',controller:'view1Ctrl'})我想懒洋洋地加载控制器和模板。 I was tempted to use something like: 我很想使用类似的东西:

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

using browserify but then it doesn't seems to be clean and not even with require. 使用browserify,但它似乎并不干净,甚至没有要求。 I know this question has been asked several times on SO some way or the other but i haven't found a emphatic answer to this. 我知道这个问题在某种程度上已被问过几次,但我没有找到一个有力的答案。

My preference here is to use the browserify as it supports the much loved cjs modules in browser. 我的偏好是使用browserify,因为它支持浏览器中备受喜爱的cjs模块。

I'm not sure how to do this with Browserify, as I've never tried it myself but I would strongly recommend you look into ocLazyLoad . 我不确定如何使用Browserify,因为我自己从未尝试过,但我强烈建议您查看ocLazyLoad

As a standalone service, it works wonders with loading files (json, css, js, templates - you name it) and injecting it into your already running angular application. 作为一个独立的服务,它可以创建加载文件(json,css,js,模板 - 您的名字)并将其注入已经运行的角度应用程序中。

With that said, it works even better (imo) coupled with a router (the default angular one, or ui-router). 话虽如此,它更好地 (imo)与路由器(默认的角度或ui路由器)相结合。

There are some 'seed projects' that showcase how one could do it with ocLazyLoad coupled with SystemJS. 有一些'种子项目'展示了如何使用ocLazyLoad和SystemJS来实现它。


But you don't even need that. 但你甚至不需要那样做。

If you go with ui-router, ui-router-extras and ocLazyLoad you can put something like this together to lazy load states: 如果你使用ui-router,ui-router-extras和ocLazyLoad,你可以把这样的东西放到懒惰的负载状态:

main.js main.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);
});

That's the 'framework' out of the way - now you just need to keep adding more modules, with more code, and match a real state definition with the dummy one in the lazyLoadedStates constant. 这就是“框架” - 现在你只需要继续添加更多模块,使用更多代码,并将实际状态定义与lazyLoadedStates常量中的虚拟定义相匹配。

about.module.js 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 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);
});

I hope that gives you the rough idea of how to setup lazy loaded states in Angular. 我希望这能让您大致了解如何在Angular中设置延迟加载状态。 I have yet to find an easier way to do this, but I'm sure there are articles out there on how to couple ui-router (or the default angular router) with some other 'lazy-loader'. 我还没有找到一种更简单的方法来做到这一点,但我确定有关于如何将ui-router(或默认的角度路由器)与其他'lazy-loader'耦合的文章。

Doc links: 文档链接:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM