angular大写指令,继承, 防止XSS攻击, 没有ngOnInit的组件初始化

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;
}
posted @ 2022-10-25 15:59  猫神甜辣酱  阅读(102)  评论(0编辑  收藏  举报