myml / myml.github.io

myml的个人网站
https://myml.dev
3 stars 0 forks source link

angular技巧 #13

Open myml opened 6 years ago

myml commented 6 years ago

NgIf

ngIf可使用as来存储临时变量,对使用async来说很方便

<ng-container *ngIf="appInfo$|async as $appInfo;else $progress">
  {{$appInfo|json}}
</ng-container>
<ng-template #$progress let-$appInfo>
  <progress *ngIf="$appInfo===null;else $error"></progress>
  <ng-template #$error>数据为空</ng-template>
</ng-template>

ngIf对返回结果为false,null,0,undefault等都有作用,所以上面代码在progress里判断appInfo为null还是其他,async在加载未完成时输出为null

ngZone

zone是angular变更检测的新方式,通过劫持window上的常用异步函数,包括setTimeout,setInterval,addEventListener等来进行变更检测。

runOutsideAngular

这个函数可以用来运行想逃避变更检测的代码,我遇到的一个情况:在使用materialize的toast(类似安卓的通知功能,在数秒后自动消失)时,其内部使用的setTimeout实现,导致angular非常频繁的进行变更检测,在ngAfterViewChecked里打印日志可以看到。当页面较为复杂或内容较多时,会导致界面卡顿。这时候就可以把toast放到runOutsideAngular里运行。

run

举个简单的例子

  title = 'app';
  constructor(private zone: NgZone) {
    window['setTitle'] = title => {
      this.title = title;
    };
  }

这个例子在window上定义了一个函数,当你在开发者模式console里执行这个函数时,会发现模板并不会刷新,angular是检测不到数据变动的

      this.zone.run(() => {
        this.title = title;
      });

这样就可以了。这种问题平常很少遇到,我是在使用qtwebchannel时遇到的,angular检测不到channel的回调,导致模板不刷新或刷新延迟,刷新延迟的情况是因为其他事件触发了angular的变动检测