28 October 2020

Custom Modal mở bằng Service Angular 2+

Use

2020
import {
  Component,
  OnInit,
} from '@angular/core';
import { ApiService } from '../../shared/services/api.service';
import { PushMessageService } from '../../shared/services/push-message.service';

@Component({
  selector: 'app-website',
  templateUrl: './website.component.html',
  styleUrls: ['./website.component.scss'],
})
export class WebsiteComponent implements OnInit {
  
  constructor(
    private api: ApiService,
    private pushMessage: PushMessageService,
  ) { }

  ngOnInit() { }

  duplicateProject(item) {
    const config = {
      type: 'submit',
      title: 'Duplicate',
      content: 'Do you want to duplicate \n This project ?',
      submitLabel: 'Duplicate'
    };
    this.pushMessage.pushMessage(config, () => {
        const params = {
          projectId: '',
          projectName: ''
        };
        this.api.post('projects/duplicate', params).subscribe(res => {
          if (res) {
            // TODO -> Call Api tại đây
            this.pushMessage.pushMessage({ type: 'confirm', title: 'Success', content: 'Your project was duplicated' });
          }
        });
    });
  }

}

Service

2020
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class PushMessageService {

  public message: BehaviorSubject<any> = new BehaviorSubject(null);
  public cb: any; 

  constructor() { }

  public pushMessage(e, cb) {
      this.message.next(e);
      this.cb = cb;
  }

  public submitMessage(e) {
       if(this.cb) this.cb()
  }
}

Component

2020
import { ViewChild } from '@angular/core';
import { Component, OnInit } from '@angular/core';
import { ModalDirective } from 'ngx-bootstrap/modal';
import { PushMessageService } from '../../services/push-message.service';

interface Message {
  type: string;
  title: string;
  content: string;
  cancelLabel: string;
  submitLabel: string;
}

@Component({
  selector: 'app-confirm-modal',
  templateUrl: './confirm-modal.component.html',
  styleUrls: ['./confirm-modal.component.scss']
})
export class ConfirmModalComponent implements OnInit {
  @ViewChild(ModalDirective, { static: false }) modal: ModalDirective;

  public model: Message;

  constructor(
    private pushMessageService: PushMessageService,
  ) {
    this.pushMessageService.message.subscribe({
      next: value => {
        if (value) {
          this.model = value;
          this.modal.show();
        }
      }
    });
  }

  ngOnInit(): void {
  }

  onSubmit() {
    this.modal.hide();
    this.pushMessageService.submitMessage(this.model.type);
  }

  onCancel() {
    this.modal.hide();
  }
}

Html

2020
<div class="modal fade" bsModal #modal="bs-modal" tabindex="-1" role="dialog" aria-labelledby="dialog-nested-name1">
  <div class="modal-dialog modal-md modal-dialog-centered">
      <div class="modal-content">
          <div class="modal-header">
              <h5 class="modal-title">{{model?.title}}</h5>
          </div>
          <div class="modal-body">
              <div class="text-center">
                  <p>{{model?.content}}</p>
              </div>
          </div>
          <div class="modal-footer">
              <button type="button" *ngIf="model?.type == 'confirm' || model?.type == 'submit'" class="btn btn_pill btn-primary" (click)="onSubmit()">{{ model?.submitLabel || 'Done'}}</button>
              <button type="button" *ngIf="model?.type == 'delete'" class="btn btn_pill btn-danger" (click)="onSubmit()">{{ model?.submitLabel || 'Delete'}}</button>
              <button type="button" *ngIf="model?.type != 'confirm'" class="btn btn-outline-primary btn_pill" [style.marginTop.px]="20" (click)="onCancel()">{{ model?.cancelLabel || 'Cancel'}}</button>
          </div>
      </div>
  </div>
</div>
Scss
2020
:host {
  .modal-dialog {
    width: 400px;
    height: 200px;

    .modal-content {
      border-radius: 24px;

      &>div {
        margin: auto;
        border: none;
      }

      .modal-header {
        padding: 0;
        margin-top: 20px;

        .modal-title {
          margin: 0;
          font-size: 40px;
          font-family: "SF Pro Text-Heavy";
          line-height: 1;
        }
      }

      .modal-body {
        font-size: 20px;
        font-family: "SF Pro Text-Regular";
        white-space: pre-line;
        line-height: 1.2;
      }

      .modal-footer {
        display: block !important;
        padding-top: 0;
        padding-bottom: 20px;

        .btn {
          margin: 0;
          width: 350px;
          height: 48px;
          font-size: 20px;
          font-family: "SF Pro Text-Bold";
          display: flex;
          align-items: center;
          justify-content: center;
        }

        .btn-outline-primary {
          &:hover {
            color: #0000E8;
            background-color: #FFFFFF;
          }
        }
      }

    }
  }
}

0 nhận xét:

Post a Comment

 

BACK TO TOP

Xuống cuối trang