微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Angular中的自定义类装饰器-了解上述代码

如何解决Angular中的自定义类装饰器-了解上述代码

我从互联网上获得了以下代码,用于实现从互联网上自动退订:

@Component({...})
export class AppComponent implements OnInit,OnDestroy {
    notifier = new Subject()
    ngOnInit () {
        var observable$ = Rx.Observable.interval(1000);
        observable$.pipe(takeuntil(this.notifier))
        .subscribe(x => console.log(x));
    }
    ngOnDestroy() {
        this.notifier.next()
        this.notifier.complete()
    }
}

不是在angular应用程序的组件中使用相同的代码,而是创建了以下自定义类装饰器:-

// For redefining OnDestroy interfacae
export interface OnDestroy {
    readonly destroyed$?: Observable<boolean>;
    ngOnDestroy(): void;
}

// Function to check if the parameter passed is type of "function"
function isFunction(value) {
    return typeof value === 'function';
}

// Class Decorator Factory
export function takeuntilDestroy(destroyMethodName = 'ngOnDestroy') {

    // Would retrun a modified constructor for the class where this class decotator would be applied
    return <T extends new (...args: any[]) => {}>(constructor: T) => {
    
    // Get access to the method 'ngOnDestroy' on the class
        const originalDestroy = constructor.prototype[destroyMethodName];

    // check if a function with name 'ngOnDestroy' exists or not. if not,throw a warning message.
        if (!isFunction(originalDestroy)) {
            console.warn(`${constructor.name} is using @takeuntilDestroy but does not implement ${destroyMethodName}`);
        }
    
    // a modified constrcutor would be returned here
        return class extends constructor {
    
      // a new observable would be created
            takeuntilDestroy$: Subject<boolean> = new Subject();

        // ??    
            get destroyed$() {
                this.takeuntilDestroy$ = this.takeuntilDestroy$ || new Subject();
                return this.takeuntilDestroy$.asObservable();
            }
            
            // ngOnDestroy method present in class is being redefined
            [destroyMethodName]() {
                if (isFunction(originalDestroy)) {
            //??
                    originalDestroy.apply(this,arguments);
                }
                this.takeuntilDestroy$.next(true);
                this.takeuntilDestroy$.complete();
            }
        };
    };
}

// ?? 
export const untilDestroyed = that => <T>(source: Observable<T>) => {
    if (!('destroyed$' in that)) {
        console.warn(`'destroyed$' property does not exist on ${that.constructor.name}`);
        return source;
    }
    return source.pipe(takeuntil<T>(that.destroyed$));
};

//The following is how the above was used in the component:
import { takeuntilDestroy,untilDestroyed } from '../../../somefilename';

@takeuntilDestroy()
@Component({
  selector: 'my-comp',templateUrl: './my-comp.html'
})

testbservable$: Observable<any>;

    this.testObservable$ = this.mts.buy(buyReqBody);
    this.testObservable$
      .pipe(untilDestroyed(this))
      .subscribe((res: BuyResponse) => {
    // some code
      },(error) => {
          // some code
        }
      );

代码用于自动退订工作。这是基于chrome中提供的一些性能测试工具。

有人可以帮助我理解代码吗?我已经标记了// ??征求意见。我花了很多时间,但似乎我无法完全理解代码

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。