简体   繁体   中英

how to correctly display alerts, so that it automatically closes after clicking 'back'

I have created success alerts, which is displayed after successfully editing or deleting the post, but there is one issue. When I perform the operation, click the 'back' button and open another post, the alert message still remains displayed until I click 'X' close button. I know that it can be solved through changing the alert status after clicking 'back' but I wonder if there is a better solution. For example, creating an observable to display the alerts, and unsubscribing it at the end of each function. What do you think, how should I solve this?

Here is my component.ts file:

import { Component, OnInit, OnDestroy } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { FormService } from './forms.service';
import { HttpClient } from '@angular/common/http';
import { alert } from './alert';

@Component({
  selector: 'app-forms',
  templateUrl: './forms.component.html',
  styleUrls: ['./forms.component.css']
})


export class FormsComponent implements OnInit {

  alert: alert;
  id: any;
  posts: any;

  constructor(public formService: FormService ,private route: ActivatedRoute,
    private router: Router, private http: HttpClient) { }



  ngOnInit() {
    this.id=this.route.snapshot.params['id'];
    this.alert = new alert();

    this.posts = this.formService.getForms(this.id).subscribe(
      (forms: any) => {
        this.formService.form = forms[0];
      }
    );
  }

  editPost() {
    this.formService.editForm()
    .then((res:any) => {
      this.formService.alert.setAlert("Post has been successfully saved !");
    })
  }

  deletePost() {
    this.formService.deleteForm()
    .subscribe(
      data  => {
        console.log("DELETE Request is successful ", data);
          this.formService.alert.setAlert("Post has been successfully deleted !");
      },
      error  => {
        console.log("Error", error);
      }
    )
  }

}

Here is my service.ts file:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { form } from './form-interface';
import { alert } from './alert';


@Injectable({
    providedIn: 'root'
}) 

export class FormService {

  formsUrl = "https://jsonplaceholder.typicode.com/posts";
  form: form = {
      id: 0,
      userId: 0,
      title: '',
      body: ''
  };
  alert: alert;


    constructor(private http: HttpClient) { 
      this.alert = new alert();
    }

    getForms(id) {
            return this.http.get('https://jsonplaceholder.typicode.com/posts'
            + "?id=" + id)
    }

    editForm() {
        return fetch(this.formsUrl + "/" + this.form.id, {
          method: 'PUT',
          body: JSON.stringify(this.form),
          headers: {
            "Content-type": "application/json; charset=UTF-8"
          }
        })
        .then(response => response.json())
    }

    deleteForm() {
        return this.http.delete(this.formsUrl + "/" + this.form.id);
    }

}

Here is my alert.ts file:

    export class alert{
        "status" : boolean;
        "text": string;
        constructor(){
            this.status=false;
            this.text="";
        }
        public setAlert(text){
            this.status = true;
            this.text = text;
        }
        public close(){
            this.status = false;
        }
    }

And here is my html file:

<div class="container">
    <a class="btn btn-primary pull-right" routerLink = '/posts' >
      Back
      </a>
</div>

<div class="container">
    <h2>Edit:</h2>
</div>

<div class="forms container">
  <form #postForm="ngForm">
      <div class="form-group">
          <label for="title">Title</label>
          <input [(ngModel)]="formService.form.title"
          name="title"  
          id="title" 
          type="text" 
          class="form-control"
          >
      </div>
      <div class="form-group">
        <label for="body">Body</label>
        <textarea [(ngModel)]="formService.form.body" 
        name= "body" 
        id="body" 
        cols="30" 
        rows="10" 
        class="form-control"
        ></textarea>
      </div>
      <button class="btn btn-success" (click) = "editPost()">Save</button>
      <button class="btn btn-danger pull-right" (click) = "deletePost()">Delete</button>

      <div class="container mt-4">
        <div class="row">
          <div class="col">
            <div *ngIf = "formService.alert.status"  class="alert alert-success 
            alert-dismissible fade show" role="alert">
              <button type="button" class="close" data-dismiss="alert" aria-label="Close"
              (click) = "formService.alert.close()">
                <span aria-hidden="true">&times;</span>
              </button>
              {{formService.alert.text}}
            </div>  
          </div>
        </div>
      </div>

    </form>
</div>

If you want to wipe the alert dialog whenever you click somewhere, I'd suggest you to add an observable to listen the click event on your document . Don't forget to inject ElementRef in your class constructor, and proper imports for takeWhile , Subscription , BehaviorSubject , and Observable . You might need to use pipe regarding your rxjs version.

private alertOpened$ = new BehaviorSubject(false); // your alert is closed by default
private isOpenedSubscription: Subscription;
private clickSubscription: Subscription;
private isAlive = true; // auto unsubscribe

public ngOnInit() {
  this.isOpenedSubsscription = this.alertOpened$
    .takeWhile(() => this.isAlive)
    .subscribe((isAlertOpened) => {
      if (!isAlertOpened && this.clickSubscription) {
        this.clickSubscription.unsubscribe();
      }
      this.clickSubscription = Observable.fromEvent(document, 'click')
        .takeWhile(() => this.isAlive)
        .subscribe((event: MouseEvent) => {
          if (!this.elemRef.nativeElement.contains(event.target)) {
            this.formService.setAlert(null);
            this.alertOpened$.next(false);
          }      
        });
    });
  }

public ngOnDestroy() {
  this.isAlive = false;
}

editPost() {
    this.formService.editForm()
    .then((res:any) => {
      this.alertOpened$.next(true);
      this.formService.alert.setAlert("Post has been successfully saved !");
    })
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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