rxjs
const nums = of(1, 2, 3);
const value = map((val: number) => val * val);
const valueNum = value(nums);
valueNum.subscribe((v) => console.log(v));
指令
@HostBinding('attr.data-xxx')
@Input() type:'aaa'|'bbb'|'ccc'='ccc'
angular 修改路徑
tsconfig.json
"compilerOptions": {
.....
"paths": {
"@domain": ["./src/app/domain/*"]
"@repo": ["./src/app/repository/*" ]
}
}
使用可以直接從路徑在找
import { GENERIC_DATA, IGenericData } from '@domain';
import { GenericDataRepository } from '@repo';
繼承調用繼承的生命週期
export class OneExtendsComponent implements OnInit {
constructor() {
}
ngOnInit(): void {
console.log('測試進行了嗎');
}
add() {
console.log(1);
}
}
export class OneComponent extends OneExtendsComponent implements OnInit {
constructor() {
super();
}
ngOnInit(): void {
this.add();
// 可以使用super關鍵字來引用基類實例並在被覆蓋的方法中調用原始方法
super.ngOnInit();
}
}
大寫指令
@Directive({
selector: '[toUppercase]',
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => ToUppercaseDirective),
multi: true
}]
})
export class ToUppercaseDirective implements ControlValueAccessor {
private onChange: (val: string) => void;
private onTouched: () => void;
constructor(
private elementRef: ElementRef,
private renderer: Renderer2
) {
}
@HostListener('input', ['$event.target.value'])
onInputChange(value: string) {
value = value.toUpperCase()
this.updateTextInput(value);
this.onChange(value);
}
@HostListener('blur')
onBlur() {
this.onTouched();
}
private updateTextInput(value: string) {
this.renderer.setProperty(this.elementRef.nativeElement, 'value', value);
}
// ControlValueAccessor Interface
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
setDisabledState(isDisabled: boolean): void {
this.renderer.setProperty(this.elementRef.nativeElement, 'disabled', isDisabled);
}
writeValue(value: any): void {
if (value == null) {
value = ''
}
this.updateTextInput(value);
}
}
防止XSS 攻擊
<textarea [(ngModel)]="str" (ngModelChange)="changeModel($event)"></textarea>
<div [innerHTML]="strHtml"></div>
export class OneComponent implements OnInit {
str = '';
strHtml = '';
constructor(@Inject(DomSanitizer) private readonly sanitizer: DomSanitizer) { }
ngOnInit(): void { }
public changeModel($event: any): void {
this.unwrap($event);
}
unwrap(value: SafeValue | null): void {
this.strHtml = this.sanitizer.sanitize(SecurityContext.HTML, value) || '';
}
}
!:或者?:
!: 等下賦值
?: 可能會賦值,所以可能會爲undefined
沒有 ngOnInit 的組件初始化的使用
傳統
data: MyData;
constructor(private readonly dataService: DataService) { }
ngOnInit() {
this.dataService.getData().subscribe(
data => this.data = data,
);
}
修改後
readonly data$ = this.dataService.getData().pipe(
map((response) => {
const first = response.data[0];
return {
name: response.name,
time: new Date(response.time)
}
}),
);
constructor(private readonly dataService: DataService) { }
使用
<p> {{ (data$ | async).name }} </p>
重構嵌套流
傳統
hero?: { name: string };
constructor(
private readonly route: ActivatedRoute,
private readonly heroService: HeroService,
) { }
ngOnInit() {
this.route.params.subscribe(
(params) = > {
const id = params.id;
this.heroService.getHero(id).subscribe(
response => this.hero = response
);
}
)
}
修改
<>
readonly hero$ = this.route.params.pipe(
switchMap(params => this.heroService.getHero(params.id))
);
constructor(
private readonly route: ActivatedRoute,
private readonly heroService: HeroService,
) { }
Input拿到值的用法
傳統
export class NameComponent implements OnInit {
@Input() name: string;
@Input() surname: string;
fullName: string;
ngOnInit() {
this.fullName = `${this.name} ${this.surname}`;
}
}
爲了防止值的變更, 我們應該使用 ngOnChanges
export class NameComponent implements OnChanges {
@Input() name: string;
@Input() surname: string;
fullName: string;
ngOnChanges() {
this.fullName = `${this.name} ${this.surname}`;
}
}
我們應該使用
export class NameComponent {
@Input() name: string;
@Input() surname: string;
get fullName(): string {
return `${this.name} ${this.surname}`
}
}
或者使用
interface MyDTO {
data: {
name: string;
time: string;
}[]
}
export class TimeComponent {
@Input()
set vm(value: MyDTO) {
const first = value.data[0];
this.time = new Date(first.time);
}
time: Date;
}