简体   繁体   English

在打字稿中,如何创建添加装饰器的装饰器?

[英]In typescript how to you create a decorator that adds a decorator?

In Angular, I'm trying to prompt the user when closing the window with a dirty form. 在Angular中,我尝试在使用脏表单关闭窗口时提示用户。 I have code that works with by listening to window:beforeunload , but the same code is duplicated on every Component . 我有可以通过监听window:beforeunload的代码,但是在每个Component上都重复了相同的代码。 I am trying to add a decorator that can be placed on the component that will mix-in the required logic, but that requires add a function and then applying a decorator on it. 我试图添加一个装饰器,该装饰器可以放置在将混合所需逻辑的组件上,但这需要添加一个函数,然后在其上应用装饰器。 My attempt is below, but it doesn't seem to be working (ie, my event listener is never called). 我的尝试在下面,但是似乎没有用(即,从未调用我的事件监听器)。

export function createOnBeforeUnload() {
    return function ($event: any) {
        console.log('calling onBeforeUnload', this, $event);
        if (this.isDirty && this.isDirty()) {
            console.log('setting message');
            $event.returnValue = DIRTY_CONFIRM_MSG;
        }
    };
}


export function DirtyChecking() {
    return function (target: any) {
        if (target.prototype) {
            console.log('adding dirty checking to', target);
            target.prototype._onBeforeUnload = createOnBeforeUnload();
            // attempt at adding the @HostListener decorator
            HostListener('window:beforeunload', ['$event'])(target.prototype._onBeforeUnload);
        }
    };
}

My component is 我的组件是

@DirtyChecking()
@Component({
    template: `
    <h2>Dirty Checker</h2>

    <form novalidate>

      <div class="form-group">
        <label for="dirty">Dirty?</label>
        <input class="form-control" type="checkbox" id="dirty" name="dirty"
               [(ngModel)]="dirty">
      </div>

    </form>
  `,
})
export class DemoDirtyCheckerComponent implements IsDirty {

    private dirty = false;

    constructor() {
    }

    toggle() {
        this.dirty = !this.dirty;
    }

    isDirty() {
        console.log('is dirty demo?', this.dirty);
        return this.dirty;
    }
}

The decorator is being called because I see "adding dirty checking to" in the console. 之所以调用装饰器,是因为我在控制台中看到“向其添加脏检查”。 However, when I close the window _onBeforeUnload isn't being called like I expect to to have be. 但是,当我关闭窗口时, _onBeforeUnload不会像我期望的那样被调用。

I took the solution suggested from @Harry Ninh 我接受了@Harry Ninh提出的解决方案

import { HostListener } from '@angular/core';

export abstract class IsDirtyComponent {
    abstract isDirty(): boolean;

    @HostListener('window:beforeunload', ['$event'])
    onBeforeUnload($event: any): void {

        if (this.isDirty()) {
            $event.returnValue = 'Are you sure?';
        }
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM