使用ocLazyLoad实现AngularJS模块按需懒加载

复杂的AngularJS SPA项目需要用路由来管理各个产品模块之间的切换。各个模块的代码如何引入?通常我们的简单做法是在首页将各个模块的代码全部引入,即使首页本身很简单也需要加载很多无用的代码。这样 一来会造成首屏加载时间过长。怎么做到首屏只引入需要显示的必要代码,而在必要的时候再去加载各个模块的代码,做到按需懒加载呢?

可能最容易想到的是使用RequireJS,网上也有这样的方案介绍,甚至有一些脚手架工程供我们使用。不过RequireJS的侵入式代码恐怕不是每个人都很接受的,万一哪天使用改成CMD、XMD又不得不改动代码,使用RequireJS只能算可行方案。有没有更好的方案呢?试一试ocLazyLoad,目前已经是1.0版本,比较稳定了。

一、快速入门

1. 下载ocLazyLoad.js。可以在git存储库的dist文件夹中找到该文件,也可以通过bower install oclazyload or npm install oclazyload来安装
2. 将oclazyLoad模块添加到应用程序中:

var myApp = angular.module("MyApp", ["oc.lazyLoad"]);

3. 按需加载:

myApp.controller("MyCtrl", function($ocLazyLoad) {
  $ocLazyLoad.load('testModule.js');
});

使用$ocLazyLoad可以加载AngularJS模块, 但如果要加载任何组件(控制器/服务/过滤器/…) 而不用定义新模块也是完全有行的 (只是确保在现有模块中定义了此组件)。

二、实例

下面的实例使用angular-ui-router和ocLazyLoad实现了AngularJS模块按需懒加载。

index.html

<body ng-app="mainApp">
  <nav>
    <ul>
      <li><a ui-sref="home" ui-sref-active="active">Home</a></li>
      <li><a ui-sref="product" ui-sref-active="active">Product</a></li>
    </ul>
  </nav>
  <ui-view></ui-view>
  <script src="app.js"></script>
</body>

views/product.html

<section>{{text}}</section>

app.js

angular.module('mainApp', ['ui.router', 'oc.lazyLoad'])
  .config(function($urlRouterProvider, $stateProvider) {
    $urlRouterProvider.otherwise('/home');

    $stateProvider
      .state('product', {
        url: '/product',
        templateUrl: 'views/product.html',
        controller: 'ProductCtrl',
        resolve: {
          loadProduct: ['$ocLazyLoad', function($ocLazyLoad) {
            return $ocLazyLoad.load('./js/product.js');
          }]
        }
      })
      .state('home', {
        url: '/home',
        template: '<div>This is the home page</div>'
      });
  });

js/product.js

angular.module('productApp', [])
  .controller('ProductCtrl', function($scope) {
    $scope.text = 'This is Product';
  });

css/style.css

a {
  text-decoration: none;
  color: #333;
}
a:hover {
  color: #900;
  text-decoration: underline;
}
a.active {
  text-decoration: underline;
}

上述实例中,最关键的步骤是我们设置路由状态对象的resolve参数,指定当前controller依赖于$ocLazyLoad.load()方法动态加载的模块或其它任何组件,这实现了模块按需懒加载。剩下的就是分模块开发了,是不是比RequireJS方式更简单友好呢?

mLab数据API

简单也说,你不用写后台服务,直接免费使用mLab的RESTful服务做CRUD纯前端应用。是不是想试一试了。且慢,您得先了解一下mLab数据API。mLab数据库可以通过两种方式应用程序访问。

第一种方法(强烈推荐):使用一个可用的驱动程序连MongoDB。如果使用的驱动程序,根本不需要使用mLab数据API。事实上,使用驱动程序能提供更好的性能、更好的安全性和更多的功能。

第二种方法:正如下面具体描述的,通过mLab的RESTful数据API连接。但请记住一个原则:只有在你不能使用MongoDB的驱动程序时才使用该方法。
继续阅读“mLab数据API”

使用bootstrap自定义下拉框

下拉框在不同的浏览器会显示成不同的UI,我们可以对其渐进增强,通常情况下用select和option元素设置数据再将其隐藏,然后用div、span、ul、li这些来替换渲染,这样不同的浏览器也会显示成统一的UI了。这样实现起来也不是那么容易的,如果我们的项目用到bootstrap,可以借助下拉菜单组件(dropdown)来简单自定义下拉框。直接上代码了: 继续阅读“使用bootstrap自定义下拉框”

Bootstrap表单验证

表单验证是很常见的功能,Bootstrap提供发很多表单验证的样式,比如说文本、标签、按钮都有success、info、warning、danger几种样式来可以在表单验证时用派上用场。如果熟悉Bootstrap JavaScript插件,甚至还可以使用警告框(Alert)、弹出框(Popover)、模态框(Modal)来实现表单验证。仅用CSS是不可能表单验证的,使用Bootstrap JavaScript插件也难以实现代码的重用。本文讲解的是另外一种实现方式,Bootstrap结合jQuery validation插件来进行表单验证的重用。 继续阅读“Bootstrap表单验证”