angular技巧
目录
声明
declarations: [AppComponent]
组件、管道、指令
引入模块
imports: [BrowserModule, AppRoutingModule]
其他模块
服务
providers: [UserService]
此模块将生成的根组件
例子:
bootstrap: [AppComponent]
此模块将生成的主要组件(组件树的顶部父节点)
动态生成的组件
例子:
entryComponents: [PopupComponent]
动态生成的组件(例如使用 ViewContainerRef.createComponent())
出口
例子:
export: [TextDirective, PopupComponent, BrowserModule]
我们希望在另一个模块中访问它们的组件、指令、模块或管道(在导入此模块后)
去掉测试文件
"schematics": {
"@schematics/angular:component": {
"style": "scss",
"skipTests": true
},
"@schematics/angular:application": {
"strict": true
},
"@schematics/angular:directive": {
"skipTests": true
},
"@schematics/angular:modules": {
"skipTests": true
},
"@schematics/angular:pipe": {
"skipTests": true
},
"@schematics/angular:service": {
"skipTests": true
},
"@schematics/angular:class": {
"skipTests": true
}
},
模块的使用
textOne.ts
export const a = 1;
export const b = 2;
使用
import * as textOne from './textOne'
console.log(textOne.a);
combineLatest
多个请求合并成一个
combineLatest(
this.http.getAllReceivers(),
this.http.getAllReceiverGroups(),
this.http.getAllShiftPlans(),
(recipient, recipientGroup, schedulePlan) => ({
recipient,
recipientGroup,
schedulePlan,
})
).subscribe(({recipient, recipientGroup, schedulePlan}) => {
});
ts技巧
const closureLibraryLocales = [
'af', 'am', 'ar', 'ar-DZ', 'az', 'be', 'bg', 'bn', 'br', 'bs',
'ca', 'chr', 'cs', 'cy', 'da', 'de', 'de-AT', 'de-CH', 'el', 'en-AU',
] as const;
type ClosureLibraryLocaleName = typeof closureLibraryLocales[number];
// "af" | "am" | "ar" | "ar-DZ" | "az" | "be" ...
const a: ClosureLibraryLocaleName='af'
const closureLibraryAliases: {[l in ClosureLibraryLocaleName]?: string[]} = {
'id': ['in'],
'he': ['iw']
}
angular 各版本的兼容
https://gist.github.com/LayZeeDK/c822cc812f75bb07b7c55d07ba2719b3#file-angular-cli-node-js-typescript-rxjs-compatiblity-matrix-csv
FormArray 倒序删除
其实就是清空, 或者用while删除
一直删除第一项
if (this.getKvArr.length) {
for (let i = this.getKvArr.controls.length; i-- > 0;) {
const valItem = this.getKvArr.at(i);
if (!this.keys.some(key => key.tag === valItem.get('key').value)) {
this.getKvArr.removeAt(this.getKvArr.length - i);
}
}
}
为啥不用
clear()
去清空, 因为需要上,我至少要保留一项, 而不是全部清空
一种有效取消订阅的方式
可以把订阅放到服务里面
@Injectable()
export class Destroy extends Observable<void> implements OnDestroy {
private readonly destroySubject$ = new Subject();
constructor() {
}
ngOnDestroy(): void {
this.destroySubject$.next();
this.destroySubject$.complete();
}
}
引入
constructor(
private readonly destroy$: Destroy
) {}
.pipe(takeUntil(this.destroy$))
服务的使用
providers: [
{
provide: 'demo1',
useFactory: (demoService: DemoService): Array<number> => {
console.log(demoService.loadRoute);
if (demoService.loadRoute) {
return [1,2,3]
} else {
return [4,5,6]
}
},
deps: [DemoService],
multi: true,
}
]
@Injectable({
providedIn: 'root'
})
export class DemoService {
loadRoute = Math.random() * 10 > 5;
constructor() {
}
}
可以做一些延迟加载的配置
组件传入的参数
<app-report2 [size]="1" data-size="10"></app-report2>
组件
@Input()
@HostBinding('attr.data-size')
size = 100;
如果值
size=1
, 那么属性的值data-size
和size
都为 1如果
size不输入
,那么默认data-size
和size
都为100
var
两个参数
- 第一个有,取第一个, 第一个没有取第二个
- 相当于第二个是默认值
:host {
--sex: red;
}
.aaa {
background-color: var(--sex, blue); /* red */
background-color: var(--sex, blue); /* blue */
}
DomSanitizer 防止XSS攻击
export class Report2Component implements OnInit, AfterViewInit {
color1 = '#f4f4f4';
html1 = `<h1>我是一个h1标签</h1>`;
getHtml(): SafeHtml {
return this.sanitizer.bypassSecurityTrustHtml(this.html1);
}
getColor(): SafeStyle {
return this.sanitizer.bypassSecurityTrustStyle(this.color1);
}
}
<p [style.background]="getColor()">kkkkkkkkkk</p>
<div [innerHTML]="getHtml()"></div>
HostBinding
export type TuiSizeXL = 'm' | 'l' | 'xl';
const WIDTH: Record<TuiSizeXL, number> = {
m: 0.25,
l: 0.375,
xl: 0.5625,
};
@HostBinding('style.fontSize')
get strokeWidth(): number {
return WIDTH[this.size];
}
如果
size
值发现变化, 对应的值也会跟着变化可以替代
Input() set
父传子修改的对应修改
决定自己的高度的是你的态度,而不是你的才能
记得我们是终身初学者和学习者
总有一天我也能成为大佬