runOutsideAngular; Subject 相关;范型 等。
一、runOutsideAngular 官方解释
this.ngZone.runOutsideAngular(() => {
fromEvent(window, 'resize')
.pipe(debounceTime(50))
.subscribe(() => {
// do something
// 1、这里修改组件的变量,界面不会更新
// 2、如果先用viewChild拿到元素的引用,操作viewChildDom 界面会更新。
// 3、当需要触发ng的变更监测,使用ChangeDetectorRef.detectChanges()
});
});
目的:规避不必要的频繁的angular变更监测,
用途:用来包裹 window.scroll; window.resize;drag 等连续触发的事件, 以及自己定义的interval定时任务。(测试了三种监听写法,addEventListener, @HostListener 以及 Rxjs.fromEvent, 如果不包裹在runOutsideAngular里面,均会触发多次变更检测,就是轻轻一拖就好几十次那种;)
通俗一点解释就是 : 假如滚动屏幕的时候,某个元素需要显示/隐藏,如果不用runOutSizeAngular, angular会在滚动过程中执行很多次变更监测。
二、Subject 相关
// 创建
// 1、命名规则,2、泛型参数, 3、EMPTY
destroy$ = new Subject<void>();
subscription: Subscription | null = Subscription.EMPTY;
ngOnInit(): void {
// 订阅
this.subscription = this.destroy$.subscribe(() => );
}
ngOnDestroy(): void {
// 销毁 。
// !,null, next, complete()
this.subscription!.unsubscribe();
this.subscription = null;
this.destroy$.next();
this.destroy$.complete();
}
1、为什么subscription unsubscribe 后还要要置为 null ? 大佬的注释 " Caretaker note: we have to set these subscriptions to `null` since these will be closed subscriptions, but they still keep references to destinations (which are `SafeSubscriber`s). Destinations keep referencing `next` functions, which we pass, for instance, to `this.optionSelectionChanges.subscribe(...)`. "
如果需要置为null来解决内存泄漏,那么是不是所有array,object都要在组件销毁的时候手动置为null ?
三、泛型 参数(viewChild, Output)
@ViewChild('fixedEl', {
static: true
}) private fixedEl!: ElementRef<HTMLDivElement>;
@Output() readonly nzChange = new EventEmitter<boolean>();
四、eslint 与 any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type NzSafeAny = any;
五、使用 DOCUMENT
import { DOCUMENT } from '@angular/common';
export type NzSafeAny = any;
@Component({
// ...
exportAs: 'nzAffix',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class AComponent {
private document: Document;
constructor(
@Inject(DOCUMENT) doc: NzSafeAny
) {
this.document = doc;
}
}
1、用angular的DI Token 比直接用window.document好在哪儿?
六、关于 const 变量的书写
const NZ_CONFIG_MODULE_NAME: NzConfigKey = 'affix';
const NZ_AFFIX_CLS_PREFIX = 'ant-affix';
const NZ_AFFIX_DEFAULT_SCROLL_TIME = 20;
@Component({
// ...
})
export class NzAffixComponent {
readonly _nzModuleName: NzConfigKey = NZ_CONFIG_MODULE_NAME;
}
---------------------------------------------------------------------------------------------------------
AnimationEvent:
1、html:
<div @slideMotion (@slideMotion.done)="onAnimationEvent($event)"> ...</div>
2、ts:
import { AnimationEvent } from '@angular/animations';
animationStateChange = new EventEmitter<AnimationEvent>();
onAnimationEvent(event: AnimationEvent): void {
this.animationStateChange.emit(event);
}
less 切换 任意主题颜色
changeColor(res: any): void {
if (!this.platform.isBrowser) {
return;
}
const changeColor = () => {
(window as any).less
.modifyVars({
'@primary-color': res.color.hex
})
.then(() => {
this.nzMessageService.remove(loading.messageId);
this.nzMessageService.success(this.language === 'en' ? `Switching color successfully` : `应用成功`);
this.color = res.color.hex;
window.scrollTo(0, 0);
});
};
const lessUrl = 'https://cdnjs.cloudflare.com/ajax/libs/less.js/2.7.2/less.min.js';
if (this.lessLoaded) {
changeColor();
} else {
(window as any).less = {
async: true
};
loadScript(lessUrl).then(() => {
this.lessLoaded = true;
changeColor();
});
}
}
。。。