有个几百KB的地址库,原则上我可以使用 http 按需加载数据来减少文件大小。可我就是太变态,因为地址的修改频率非常非常低,所以要一开始就把玩意儿加载放在那不使用,就不是一个滋味。这便是变态之原因一。

我的需求里面有一个订单详情页,但详情页可以直接修改地址,问题来了,详情页打开频率非常高,而修改频率极低【注意是极低】,所以我希望当我对其进行修改操作时,再延迟加载指令。其变态之原因二。

依赖

ocLazyLoad

简单点说就是将所需要的文件加载完毕后,并返回一个 promise,这样我们可以跟路由的 resolve一起,达到一个完成的延迟加载 css/js etc.

同时,ocLazyLoad 提供一个指令,可以直接在 view 中延迟加载某个指令,也会重新编译该指令内的HTML元素 $compile(content)($scope)

<div oc-lazy-load="{name: 'TestModule', files: ['js/testModule.js', 'partials/lazyLoadTemplate.html']}">
    // Use a directive from TestModule
    <test-directive></test-directive>
</div>

看上去问题已经可以解决了,可总是那么不如意,ngIf 会打乱由于 DOM 被预编译且被缓存,那就蛋疼了。

即使重新编译也没用。

好,既然是变态做法,那自然不能够依赖 ocLazyLoad 提供的最方便免费午餐,需要一点点改进。

一个解决办法

大概分几步:

  1. 包裹一个 div,方便于只对该元素内进行重新编译,否则会出现循环编译。
  2. 调用 $ocLazyLoad.load 延迟加载所需要的文件。
  3. 已经加载过的,还需要重新编译,因为对于 ocLazyLoad 而言会保留自己的 module 信息。

那么,以下就是大概的一个方案了:

<div ng-init="cityLoad('#citySelect')">
    <city-select id="citySelect" ng-model="city.dis"></city-select>
</div>
var citySelectParam = {
    name: 'angular.city.select',
    files: ['angular-city-select/angular-city-select.min.js', 'angular-city-select/angular-city-select.min.css']
};
$scope.cityLoad = function (eleId) {
    try {
        angular.module(citySelectParam .name);
        $compile(angular.element(eleId))($scope);
    } catch (err) {
        $ocLazyLoad.load(citySelectParam ).then(function () {
        $compile(angular.element(eleId))($scope);
        });
    }
}

好了,大概就是这样子吧。希望您也有这么个变态做法。