как правильно отображать оповещения, чтобы оно автоматически закрывалось после нажатия кнопки «назад»

#javascript #angular #typescript

#javascript #angular #typescript

Вопрос:

Я создал оповещения об успешном завершении, которые отображаются после успешного редактирования или удаления записи, но есть одна проблема. Когда я выполняю операцию, нажимаю кнопку «Назад» и открываю другую запись, сообщение с предупреждением по-прежнему отображается, пока я не нажму кнопку «X» закрыть. Я знаю, что это можно решить, изменив статус оповещения после нажатия кнопки «назад», но мне интересно, есть ли лучшее решение. Например, создание observable для отображения оповещений и отмена подписки на него в конце каждой функции. Как вы думаете, как я должен это решить?

Вот мой файл component.ts:

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

}
  

Вот мой файл service.ts:

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

}
  

Вот мой файл alert.ts:

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

И вот мой HTML-файл:

 <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">amp;times;</span>
              </button>
              {{formService.alert.text}}
            </div>  
          </div>
        </div>
      </div>

    </form>
</div>
  

Комментарии:

1. Под кнопкой «Назад» вы имеете в виду кнопку «Назад» браузера или вашу собственную HTML-кнопку?

2. Вы не можете скрыть оповещение при вызове ngOnDestroy ? Или кнопка «Назад» не перемещается на другой компонент?

3. Я исправил свой пост. теперь вы можете увидеть мой HTML-файл.

4. Где я должен написать ngOnDestroy? кнопка «Назад» работает правильно, возвращаясь к компоненту posts.

5. FormsComponent можно было бы реализовать, OnDestroy а затем добавить функцию ngOnDestroy() {} , в которой вы скрываете предупреждение.

Ответ №1:

Если вы хотите удалять диалоговое окно предупреждения всякий раз, когда вы нажимаете где-либо, я бы посоветовал вам добавить observable для прослушивания click события на вашем document компьютере. Не забудьте внедрить ElementRef в свой конструктор класса и соответствующий импорт для takeWhile , Subscription , BehaviorSubject и Observable . Возможно, вам потребуется использовать pipe в отношении вашей версии rxjs.

 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 amp;amp; 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 !");
    })
  }