From 37275fc8a217e1a91c4f1fad1b5807df38c8d5f1 Mon Sep 17 00:00:00 2001 From: Morgan Touverey Quilling Date: Thu, 5 Dec 2019 23:47:26 +0100 Subject: [PATCH] feat(SweetAlert2Module, SwalComponent): implement "fire on init" strategy Closes #145 --- .../src/app/app.component.html | 19 +++++++ .../src/app/app.component.ts | 2 +- projects/ngx-sweetalert2/src/lib/di.ts | 6 ++- .../src/lib/swal.component.spec.ts | 3 +- .../ngx-sweetalert2/src/lib/swal.component.ts | 51 +++++++++++++++---- .../src/lib/sweetalert2.module.ts | 7 ++- 6 files changed, 73 insertions(+), 15 deletions(-) diff --git a/projects/ngx-sweetalert2-demo/src/app/app.component.html b/projects/ngx-sweetalert2-demo/src/app/app.component.html index 27eaffc..3da936a 100644 --- a/projects/ngx-sweetalert2-demo/src/app/app.component.html +++ b/projects/ngx-sweetalert2-demo/src/app/app.component.html @@ -21,5 +21,24 @@

Using the [swal]="swalRef" syntax with a <swal #swalRe
+

<swal [swalFireOnInit]="true"></swal>

+ + +

+ The modal's presence in the DOM is conditioned by the modalFireCondition variable.
+ As soon as this variable is set to true, the *ngIf on the <swal> element + creates the component, and the modal fires immediately since it has [swalFireOnInit]="true".
+ When the modal is closed, modalFireCondition is reset to false, the modal component is + then destroyed by *ngIf, so you can click the button again. +

+ + + +
+ Load submodule diff --git a/projects/ngx-sweetalert2-demo/src/app/app.component.ts b/projects/ngx-sweetalert2-demo/src/app/app.component.ts index b80ec54..20ef054 100644 --- a/projects/ngx-sweetalert2-demo/src/app/app.component.ts +++ b/projects/ngx-sweetalert2-demo/src/app/app.component.ts @@ -6,5 +6,5 @@ import { Component } from '@angular/core'; styleUrls: ['./app.component.css'] }) export class AppComponent { - public show = false; + public modalFireCondition = false; } diff --git a/projects/ngx-sweetalert2/src/lib/di.ts b/projects/ngx-sweetalert2/src/lib/di.ts index d2feead..04cfef7 100644 --- a/projects/ngx-sweetalert2/src/lib/di.ts +++ b/projects/ngx-sweetalert2/src/lib/di.ts @@ -1,6 +1,8 @@ import { InjectionToken } from '@angular/core'; import Swal from 'sweetalert2'; -export const swalProviderToken = new InjectionToken('@sweetalert2/ngx-sweetalert2#swalLibraryToken'); +export const swalProviderToken = new InjectionToken('@sweetalert2/ngx-sweetalert2#swalProvider'); -export const dismissOnDestroyToken = new InjectionToken('@sweetalert2/ngx-sweetalert2#dismissOnDestroy'); +export const fireOnInitToken = new InjectionToken('@sweetalert2/ngx-sweetalert2#fireOnInit'); + +export const dismissOnDestroyToken = new InjectionToken('@sweetalert2/ngx-sweetalert2#dismissOnDestroy'); diff --git a/projects/ngx-sweetalert2/src/lib/swal.component.spec.ts b/projects/ngx-sweetalert2/src/lib/swal.component.spec.ts index bf55610..bc0a639 100644 --- a/projects/ngx-sweetalert2/src/lib/swal.component.spec.ts +++ b/projects/ngx-sweetalert2/src/lib/swal.component.spec.ts @@ -1,5 +1,5 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { dismissOnDestroyToken, swalProviderToken } from './di'; +import { dismissOnDestroyToken, fireOnInitToken, swalProviderToken } from './di'; import { SwalComponent } from './swal.component'; import { SweetAlert2LoaderService } from './sweetalert2-loader.service'; @@ -13,6 +13,7 @@ describe('NgxSweetalert2Component', () => { providers: [ SweetAlert2LoaderService, { provide: swalProviderToken, useValue: () => import('sweetalert2') }, + { provide: fireOnInitToken, useValue: false }, { provide: dismissOnDestroyToken, useValue: true } ], declarations: [SwalComponent] diff --git a/projects/ngx-sweetalert2/src/lib/swal.component.ts b/projects/ngx-sweetalert2/src/lib/swal.component.ts index ee5b5e6..ee0bfd5 100644 --- a/projects/ngx-sweetalert2/src/lib/swal.component.ts +++ b/projects/ngx-sweetalert2/src/lib/swal.component.ts @@ -1,8 +1,9 @@ import { + AfterViewInit, ChangeDetectionStrategy, Component, EventEmitter, Inject, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges } from '@angular/core'; import Swal, { SweetAlertOptions, SweetAlertResult } from 'sweetalert2'; -import { dismissOnDestroyToken } from './di'; +import { dismissOnDestroyToken, fireOnInitToken } from './di'; import * as events from './swal-events'; import { SweetAlert2LoaderService } from './sweetalert2-loader.service'; @@ -32,7 +33,7 @@ import { SweetAlert2LoaderService } from './sweetalert2-loader.service'; template: '', changeDetection: ChangeDetectionStrategy.OnPush }) -export class SwalComponent implements OnInit, OnChanges, OnDestroy { +export class SwalComponent implements OnInit, AfterViewInit, OnChanges, OnDestroy { @Input() public title: SweetAlertOptions['title']; @Input() public titleText: SweetAlertOptions['titleText']; @Input() public text: SweetAlertOptions['text']; @@ -133,9 +134,19 @@ export class SwalComponent implements OnInit, OnChanges, OnDestroy { return options; } + /** + * Whether to fire the modal as soon as the component is created and initialized in the view. + * When left undefined (default), the value will be inherited from the module configuration, which is `false`. + * + * Example: + * + */ + @Input() + public swalFireOnInit?: boolean; + /** * Whether to dismiss the modal when the component is destroyed by Angular (for any reason) or not. - * When left undefined (default), the value will be inherited from the module configuration. + * When left undefined (default), the value will be inherited from the module configuration, which is `true`. */ @Input() public swalDismissOnDestroy?: boolean; @@ -144,29 +155,34 @@ export class SwalComponent implements OnInit, OnChanges, OnDestroy { * Emits an event when the modal DOM element has been created. * Useful to perform DOM mutations before the modal is shown. */ - @Output() public readonly beforeOpen = new EventEmitter(); + @Output() + public readonly beforeOpen = new EventEmitter(); /** * Emits an event when the modal is shown. */ - @Output() public readonly open = new EventEmitter(); + @Output() + public readonly open = new EventEmitter(); /** * Emits an event when the modal DOM is rendered. */ - @Output() public readonly render = new EventEmitter(); + @Output() + public readonly render = new EventEmitter(); /** * Emits an event when the modal will be closed. * If you just want to know when the user dismissed the modal, prefer the higher-level (cancel) output. */ - @Output() public readonly close = new EventEmitter(); + @Output() + public readonly close = new EventEmitter(); /** * Emits an event after the modal had been closed. * If you just want to know when the user dismissed the modal, prefer the higher-level (cancel) output. */ - @Output() public readonly afterClose = new EventEmitter(); + @Output() + public readonly afterClose = new EventEmitter(); /** * Emits when the user clicks "Confirm". @@ -179,7 +195,8 @@ export class SwalComponent implements OnInit, OnChanges, OnDestroy { * // ... save user email * } */ - @Output() public readonly confirm = new EventEmitter(); + @Output() + public readonly confirm = new EventEmitter(); /** * Emits when the user clicks "Cancel", or dismisses the modal by any other allowed way. @@ -194,7 +211,8 @@ export class SwalComponent implements OnInit, OnChanges, OnDestroy { * // ... do something * } */ - @Output() public readonly cancel = new EventEmitter(); + @Output() + public readonly cancel = new EventEmitter(); /** * This Set retains the properties that have been changed from @Inputs, so we can know precisely @@ -215,6 +233,7 @@ export class SwalComponent implements OnInit, OnChanges, OnDestroy { public constructor( private readonly sweetAlert2Loader: SweetAlert2LoaderService, + @Inject(fireOnInitToken) private readonly moduleLevelFireOnInit: boolean, @Inject(dismissOnDestroyToken) private readonly moduleLevelDismissOnDestroy: boolean) { } @@ -229,6 +248,18 @@ export class SwalComponent implements OnInit, OnChanges, OnDestroy { this.sweetAlert2Loader.preloadSweetAlertLibrary(); } + /** + * Angular lifecycle hook. + * Fires the modal, if the component or module is configured to do so. + */ + public ngAfterViewInit(): void { + const fireOnInit = this.swalFireOnInit === undefined + ? this.moduleLevelFireOnInit + : this.swalFireOnInit; + + fireOnInit && this.fire(); + } + /** * Angular lifecycle hook. * Updates the SweetAlert options, and if the modal is opened, asks SweetAlert to render it again. diff --git a/projects/ngx-sweetalert2/src/lib/sweetalert2.module.ts b/projects/ngx-sweetalert2/src/lib/sweetalert2.module.ts index a64512a..483ad78 100644 --- a/projects/ngx-sweetalert2/src/lib/sweetalert2.module.ts +++ b/projects/ngx-sweetalert2/src/lib/sweetalert2.module.ts @@ -1,6 +1,6 @@ import { CommonModule } from '@angular/common'; import { ModuleWithProviders, NgModule } from '@angular/core'; -import { dismissOnDestroyToken, swalProviderToken } from './di'; +import { dismissOnDestroyToken, fireOnInitToken, swalProviderToken } from './di'; import { SwalPortalComponent } from './swal-portal.component'; import { SwalPortalDirective } from './swal-portal.directive'; import { SwalComponent } from './swal.component'; @@ -9,6 +9,7 @@ import { SwalProvider, SweetAlert2LoaderService } from './sweetalert2-loader.ser export interface Sweetalert2ModuleConfig { provideSwal?: SwalProvider; + fireOnInit?: boolean; dismissOnDestroy?: boolean; } @@ -37,6 +38,7 @@ export class SweetAlert2Module { providers: [ SweetAlert2LoaderService, { provide: swalProviderToken, useValue: options.provideSwal || provideDefaultSwal }, + { provide: fireOnInitToken, useValue: options.fireOnInit || false }, { provide: dismissOnDestroyToken, useValue: options.dismissOnDestroy || true } ] }; @@ -50,6 +52,9 @@ export class SweetAlert2Module { SweetAlert2LoaderService, { provide: swalProviderToken, useValue: options.provideSwal } ] : [], + ...options.fireOnInit !== undefined ? [ + { provide: fireOnInitToken, useValue: options.fireOnInit } + ] : [], ...options.dismissOnDestroy !== undefined ? [ { provide: dismissOnDestroyToken, useValue: options.dismissOnDestroy } ] : []