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. In angular routes are somewhat defined like the below:
我来自backbone.js背景,在那里它很安静直接使用require.js基于路由器回调的延迟加载。角度路线在某种程度上定义如下:
// 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. I was tempted to use something like:
现在这里,$ routeProvider.when({templateURL:'.. / tmpl.html',controller:'view1Ctrl'})我想懒洋洋地加载控制器和模板。我很想使用类似的东西:
$routeProvider.when({templateURL:'../tmpl.html',controller:require('view1Ctrl'})
using browserify but then it doesn't seems to be clean and not even with require. 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.
使用browserify,但它似乎并不干净,甚至没有要求。我知道这个问题在某种程度上已被问过几次,但我没有找到一个有力的答案。
My preference here is to use the browserify as it supports the much loved cjs modules in browser.
我的偏好是使用browserify,因为它支持浏览器中备受喜爱的cjs模块。
1 个解决方案
#1
3
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来实现它。
- https://github.com/Swimlane/angular-systemjs-seed
- https://github.com/lookfirst/systemjs-seed
- https://github.com/lookfirst/ocLazyLoad-SystemJS-Router
- https://github.com/kasperlewau/ng-jspm-seed
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
/**
* 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
/**
* 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);
});
I hope that gives you the rough idea of how to setup lazy loaded states in 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'.
我希望这能让您大致了解如何在Angular中设置延迟加载状态。我还没有找到一种更简单的方法来做到这一点,但我确信有关于如何将ui-router(或默认的角度路由器)与其他'lazy-loader'耦合的文章。
Doc links:
#1
3
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来实现它。
- https://github.com/Swimlane/angular-systemjs-seed
- https://github.com/lookfirst/systemjs-seed
- https://github.com/lookfirst/ocLazyLoad-SystemJS-Router
- https://github.com/kasperlewau/ng-jspm-seed
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
/**
* 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
/**
* 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);
});
I hope that gives you the rough idea of how to setup lazy loaded states in 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'.
我希望这能让您大致了解如何在Angular中设置延迟加载状态。我还没有找到一种更简单的方法来做到这一点,但我确信有关于如何将ui-router(或默认的角度路由器)与其他'lazy-loader'耦合的文章。
Doc links: