ng-zorro UI源码技巧(一)
在Angular 中转译
转移: 将代码从一种高级语言转换为另一种高级语言。
编译:将代码从高级语言转换为机器级语言
每个 Angular 项目都有一个名为tsconfig.json
的文件,其中包含将 .js
文件转换为 .ts
文件的设置。
JIT和AOT编译的区别
- JIT 编译是在应用程序运行时完成的,而 AOT 编译是在构建过程中完成的。
angular-cdk-dir
模块注入
import {BidiModule} from '@angular/cdk/bidi';
imports: [ BidiModule, ]
文本方向
<p [dir]="dir">
可以动态切换方向
</p>
// 'ltr'(左到右)| 'rtl' (右到左)
dir = "rtl";
类似 text-align="left|right" 只是几个自带的盒子都会变成这样
可以把整个组件都添加这个效果
监听
父
<app-report2 [dir]="dir"></app-report2>
dir: Direction = 'rtl';
子
constructor(
private directionality: Directionality
) {}
ngOnInit(): void {
this.directionality.change?.subscribe((direction: Direction) => {
console.log(direction,'被改变了111');
});
}
@Component
封装策略
@Component({
encapsulation: ViewEncapsulation.Emulated 默认
})
ViewEncapsulation.Emulated
:应用修改后的组件样式以模拟原生 Shadow DOM CSS 封装行为。ViewEncapsulation.None
:在没有任何封装的情况下全局应用组件样式。ViewEncapsulation.ShadowDom
: 使用浏览器原生的 Shadow DOM API 来封装样式。
如果我们想受到上级的影响可以使用ViewEncapsulation.None
@Input 父传子进行过滤筛选
<app-report2 [bool]="1" ></app-report2>
@Input()
@InputBoolean()
bool:any = false;
InputBoolean
工具库, 我们如果写给别人用的组件, 不可能别人给了一个不符合我们规定的属性,我们就给他报错, 如果给的是其他类型, 我们可以把他强转到我们需要的类型,进行处理, InputBoolean
内部做了get,set
监控, 避免父级修改了, 儿子可以重新检测到
import {coerceBooleanProperty} from '@angular/cdk/coercion';
// 添加get set 当元素修改的时候重新执行
function propDecoratorFactory<T, D>(
name: string,
fallback: (v: T) => D
): (target: any, propName: string) => void {
function propDecorator(
target: any,
propName: string,
originalDescriptor?: TypedPropertyDescriptor<any>
): any {
const privatePropName = `$$__zorroPropDecorator__${propName}`;
console.log(target);
Object.defineProperty(target, privatePropName, {
configurable: true,
writable: true
});
return {
get(): string {
return originalDescriptor && originalDescriptor.get
? originalDescriptor.get.bind(this)()
: this[privatePropName];
},
set(value: T): void {
if (originalDescriptor && originalDescriptor.set) {
originalDescriptor.set.bind(this)(fallback(value));
}
this[privatePropName] = fallback(value);
}
};
}
return propDecorator;
}
// 我们可以自己写自定义的
export function InputBoolean(): any {
return propDecoratorFactory('InputBoolean', toBoolean);
}
// 我们可以自己写自定义的
export function toBoolean(value: boolean | string): boolean {
return coerceBooleanProperty(value);
}
host 技巧
组件的最外层添加class
或者属性
@Component({
selector: 'app-report2',
templateUrl: './report2.component.html',
styleUrls: ['./report2.component.scss'],
host:{
class:'ant-xxx',
'[class.aaa]':`bool`,
'[class.bbb]':`bool==true`,
}
})
bool 是下面组件使用的一个变量
tabindex
给div
添加获取焦点失去焦点属性
<div tabindex="-1" (blur)="changeBlur()">kkkkkkkk</div>
startWith
b = new Subject<string>();
this.b.pipe(
startWith('xxx')
).subscribe(console.log)
这样我们就不一样要使用BehaviorSubject
exportAs 别名的使用
@Component({
selector: 'button[nz-button], a[nz-button]',
exportAs: 'nzButton',
})
使用
<button nz-button nzType="primary" #aaa='nzButton'>Primary Button</button>
@ViewChild('aaa') aaa!: NzButtonComponent;
ngAfterViewInit() {
console.log(this.aaa); // NzButtonComponent
}
我们在angular.js可能用的比较多
<input type="text" [(ngModel)]="str" #strA="ngModel">
@ViewChild('strA') strA!: NgModel;
ngAfterViewInit() {
if(this.strA){
this.strA.control.valueChanges// 检测变化
}
}
stopPropagation与stopImmediatePropagation的区别
event.stopPropagation();
阻止事件冒泡。
event.stopImmediatePropagation();
阻止事件冒泡并且阻止该元素上同事件类型的监听器被触发。
可以同时用这两个, 用在按钮上
event.preventDefault();
event.stopImmediatePropagation();
默认我们阻止默认行为和停止事件传播, 所以不需要Angular运行变更检测
当我们点击按钮的时候,如果是禁用的是a链接或者loading开启的时候,就类似禁止点击
ngOnInit(): void {
this.ngZone.runOutsideAngular(() => {
fromEvent<MouseEvent>(this.elementRef.nativeElement, 'click', { capture: true })
.pipe(takeUntil(this.destroy$))
.subscribe(event => {
if ((this.disabled && (event.target as HTMLElement)?.tagName === 'A') || this.nzLoading) {
event.preventDefault();
event.stopImmediatePropagation();
}
});
});
}
开发环境和打包后的资源处理
我们打包后想引入那时候的本地网址的地址, 和本地环境进行区别
类似我们需要的本地自定义图标
导入模块
app.module.ts
providers: [
{
provide: APP_BASE_HREF,
useFactory: (s: PlatformLocation) => s.getBaseHrefFromDOM(),
deps: [PlatformLocation],
},
]
app.component.ts
constructor(
@Inject(APP_BASE_HREF) href: string
) {
this.nzIconService.fetchFromIconfont({
scriptUrl: environment.production ? href + '/assets/线上' : '../assets/本地用相对路径',
});
自定义图标的使用
<i nz-icon [nzIconfont]="'icon-tuichu'"></i>
决定自己的高度的是你的态度,而不是你的才能
记得我们是终身初学者和学习者
总有一天我也能成为大佬