首页 > 语言 > JavaScript > 正文

浅析AngularJS中的生命周期和延迟处理

2024-05-06 14:40:11
字体:
来源:转载
供稿:网友

这里,我们再讨论一些常用的高级的控制反转容器(Inversion of Control containers):延迟加载(lazy-loading),生命周期管理(lifetime management),以及延迟的创建/处理(deferred creation/resolution)。
 
延迟加载(Lazy-Loading)

所谓延迟加载就是当你需要用到对象时候才对其进行实例化。许多依赖注入系统都会在一开始就创建组件,作为它的可依赖项目。不过有时候,直到在应用中用到它们之前,你都不会想去实例化这些组件。Angular 中,一个很好的例子就是,当你在配置的时候去设置一个行为,而该行为又会引用到一些还没创建的组件。

假设你想拦截系统内建的 $log 服务,因此你把它存在了 $rootScope 里面。当然我不建议这样做,不过这样举例比较简单有效。为了拦截,你在配置的时候用到了 $provide 然后调用修饰方法。如果这时你想直接引用 $rootScope 的话,由于循环引用你会拿到个异常。而解决案是通过 $injector 延迟加载 $rootScope 。


下面的代码只会在 $rootScope 第一次被使用的时候才去加载它。

 

$provide.decorator(, [, ,   ($delegate, $injector) {     log = $delegate.log.bind($delegate);    $delegate.log = (msg) {       rs = $injector.get();       (rs.logs === undefined) {        rs.logs = [];      }      rs.logs.push(msg);      log(msg);    };     $delegate;}]);

之后的调用都会拿到一样的单例 $rootScope。 这里有个可用例子。我之前好像听过有个(不对的)说法(Angular 只支持单例) … 当然不是真的。$injector 中的方法就是用来给你管理你的组件的生命周期的。

生命周期管理

生命周期涉及到你如何管理组件的实例。默认情况,当你注入一个 Angular 的依赖,依赖注入就会帮你创建它的一个副本然后在你的应用里面重用它。大多数情况下这确实是我们所期待的。而有些情况下,会要求同一组件的多个实例。假设下面的计数服务:

 
 

Counter($log) {  $log.log();} angular.extend(Counter.prototype, {  count: 0,  increment: () {    .count += 1;     .count;  }}); Counter.$inject = []; app.service(, Counter);

你的应用要跟踪不同的计数器。而你注入该服务后,总会拿到一样的计数器。这难道是 Angular 的限制?

当然不是。重复一次,通过 $injector 服务你可以在任何时候创建一个新副本。下面的代码用了两个独立的计数器:
 

app.run([, , ,   (rs, c, i) {    rs.count = c.count;    rs.update = c.increment;    rs.update2 = () {       c = i.instantiate(Counter);      rs.count2 = c.count;      rs.update2 = () {        c.increment();        rs.count2 = c.count;      };    };  }]);

你可以看到计数器都是被独立的实例跟踪的,这里是可用例子。如果你需要经常生成新实例,你可以像这样注册服务:

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选