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

时间:2017-08-09 21:50:20

标签: angular typescript

在Angular中,我尝试在使用脏表单关闭窗口时提示用户。我有通过收听window:beforeunload来使用的代码,但每个Component都会复制相同的代码。我正在尝试添加一个可以放置在组件上的装饰器,它将混合所需的逻辑,但这需要添加一个函数,然后在其上应用装饰器。我的尝试在下面,但它似乎没有工作(即,我的事件监听器从未被调用)。

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);
        }
    };
}

我的组件是

@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;
    }
}

正在调用装饰器,因为我看到&#34;将脏检查添加到&#34;在控制台中。但是,当我关闭窗口_onBeforeUnload时,我没有像我希望的那样被调用。

1 个答案:

答案 0 :(得分:0)

我采用了@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?';
        }
    }

}