Angular 2:打开自定义模式弹出窗口并在用户关闭浏览器选项卡时锁定选项卡关闭

时间:2017-03-01 13:44:21

标签: javascript angular browser

我面临着一些非常奇怪的事情。在Angular 2 Web应用程序中,当用户关闭浏览器选项卡或浏览器本身时,我需要显示一个自定义模式弹出窗口,建议用户留下或离开(顺便向我的API发送一些操作) 。事实上,我需要在用户做出选择之前锁定标签。

下面的代码允许检测选项卡关闭,然后打开模式弹出窗口但不会阻止选项卡关闭。

有人遇到过同样的问题吗?提前感谢您的帮助。

来自app.component.ts

@HostListener('window:beforeunload', ['$event'])
private beforeUnloadHander(event) {
     this.translate.get('WINDOW.title').subscribe(
        value => {
            this.modalTitle = value
        });
     this.componentChild = {
        component: ModalCloseWindowComponent,
        inputs: {}
     };
};

来自app.component.html:

  <main>
    <router-outlet></router-outlet>
    <modal [title]="modalTitle" [componentChild]="componentChild" (onClose)="close(event)"></modal>
</main>

模态弹出窗口部分由2个组件组成,一个用于所有模态弹出窗口,另一个用于CloseWindow窗口组件。

来自modal.component.ts(通用部分):

  import { Component, Input, Output, EventEmitter, ViewChild, ViewContainerRef, ComponentRef, ComponentFactoryResolver, ReflectiveInjector } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

@Component({
    selector: 'modal',
    templateUrl: './modal.component.html'
})

export class ModalComponent {

    @ViewChild('theBody', { read: ViewContainerRef })  public theBody;
    private currentComponent: ComponentRef<any>;
    private visible = false;
    private visibleAnimate = false;
    @Output() public onClose = new EventEmitter();
    @Input() public title: string;
    // todo trouver comment géré la popup autrement pour enlever les any
    @Input() set componentChild(data: { component: any, inputs: Object[] }) {
        if (!data) {
            return;
        }
        // Injecte les inputs dont l'enfant a besion
        let inputProviders = Object.keys(data.inputs).map((inputName) => { return { provide: inputName, useValue: data.inputs[inputName] }; });
        let resolvedInputs = ReflectiveInjector.resolve(inputProviders);

        // Crée l'injecteur à partir des données que l'on veut transmettre
        let injector = ReflectiveInjector.fromResolvedProviders(resolvedInputs, this.theBody.parentInjector);

        // on crée la factory du component
        let factory = this.componentFactoryResolver.resolveComponentFactory(data.component);

        // on crée le component qui utilise l'injecteur et la factory
        this.currentComponent = factory.create(injector);

        // on insert le component dans le dom container
        this.theBody.insert(this.currentComponent.hostView);

        // Overture de la fenêtre
        this.show();

        // on souscrit des events de sortie
        // this.currentComponent = component;
        this.currentComponent.instance.onClose.subscribe(dataOnClose => {
            this.hide();
            this.onClose.emit(dataOnClose);
        });
        this.currentComponent.instance.close.subscribe(dataClose => this.hide());
    }

    constructor(private componentFactoryResolver: ComponentFactoryResolver) {
    }

    public show(): void {
        // window.parent.event.preventDefault();
        // window.parent.event.stopPropagation();
        // window.onbeforeunload = null;
        // window.parent.event.cancelBubble = true;
        //// window.parent.event.returnValue = false;
        // window.parent.event.stopImmediatePropagation();
        this.visible = true;
        this.visibleAnimate = true;
    }

    public hide(): void {
        this.visibleAnimate = false;
        if (this.currentComponent) {
            this.currentComponent.destroy();
        }
        this.currentComponent = null;
        this.visible = false;
    }
}

来自modal.component.html(通用部分):

<div class="modal fade" tabindex="-1" [ngClass]="{'in': visibleAnimate}"
     [ngStyle]="{'display': visible ? 'block' : 'none'}">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h4>{{ title }}</h4>
            </div>
            <div class="modal-body">
                <div #theBody></div>
            </div>
        </div>
    </div>
</div>
<div class="modal-backdrop fade" [ngClass]="{'in': visibleAnimate}"
     [ngStyle]="{'display': visible ? 'block' : 'none'}"></div>

来自modalCloseWindow.component.ts:

import { Component, Input, Output, EventEmitter, AfterViewInit, ElementRef  } from '@angular/core';
import { FormBuilder } from '@angular/forms';
import { TranslateService } from 'ng2-translate';

@Component({
    selector: 'modal-close-window',
    templateUrl: './modalCloseWindow.component.html'
})

export class ModalCloseWindowComponent {

    @Output() public onClose = new EventEmitter();
    @Output() public close = new EventEmitter();

    constructor(private translateService: TranslateService,
        public fb: FormBuilder) {
    }

    public hide(): void {
        this.close.emit(false);
    }

    public quitter(): void {
        this.onClose.emit(true);
    }
}

来自modalCloseWindow.component.html;

<form class="form cf">
    <div class="form-item">
        <p>{{ 'WINDOW.stopEnregistrement' | translate }} </p>
        <p>{{ 'WINDOW.infoStopEnregistrement' | translate }} </p>
    </div>
    <div class="form-actions cf">
        <button type="button" class="btn btn-cancel" (click)="hide()">{{ 'WINDOW.rester' | translate }} </button> &nbsp;
        <button type="button" class="btn btn-primary" (click)="quitter()">{{ 'WINDOW.quitter' | translate }} </button>
    </div>
</form>

0 个答案:

没有答案