Боковая панель PrimeNG очищает начальные сообщения. Почему?

В моем app.comComponent.html у меня есть

<div class = "main">
    <button type = "button" (click) = "onShowNotificationSideBar()" label = "Show"></button>  
    <p-sidebar [(visible)] = "notificationSideBarVisible" position = "right" [style] = "{width:'50em'}">
        <button type = "button" pButton pRipple (click) = "showSuccess()" label = "S" class = "p-button-success"></button>        
        <button type = "button" pButton pRipple (click) = "showWarn()" label = "W" class = "p-button-warning"></button>
        <button type = "button" pButton pRipple (click) = "showError()" label = "E" class = "p-button-danger"></button>
        <h3>Messages</h3>
        <h5>{{messages}}</h5>
        <p-messages [(value)] = "messages" [enableService] = "false" ></p-messages>
    </p-sidebar>
    <p-toast position = "center"></p-toast>
    <router-outlet></router-outlet>
</div>

в app.comComponent.ts у меня есть

import { Component } from '@angular/core';
import { Message, MessageService } from 'primeng/api';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
  providers: [MessageService]
})
export class AppComponent {
  title = 'WECO';
  notificationSideBarVisible = false;

  constructor(private messageService: MessageService) {
    messageService.messageObserver.subscribe((m:Message | Message[])=>{
      if (!Array.isArray(m)){
        this.messages.push(m)
      }
      this.messages = [...this.messages];
    });
  }

  onShowNotificationSideBar(){
    this.notificationSideBarVisible=true;
  }

  count=0;

  messages : Message[] = [
    // { severity: 'success', summary: 'Success', detail: 'Message Content' },
    // { severity: 'info', summary: 'Info', detail: 'Message Content' },
    // { severity: 'warn', summary: 'Warning', detail: 'Message Content' },
    // { severity: 'error', summary: 'Error', detail: 'Message Content' }
  ];

  longSentence = 'Let’s end all this nonsense about how long sentences = run-on sentences. You can have a six-word run-on sentence (“I went shopping I ate donuts.”), while most of the sentences below are much, much longer than that and are not run-ons';//'And let’s end all this nonsense about how long sentences = run-on sentences. You can have a six-word run-on sentence (“I went shopping I ate donuts.”), while most of the sentences below are much, much longer than that and are not run-ons (except for a few examples like Jose Saramago).  But whether the sentence is grammatically correct isn’t nearly as important as whether the sentence is fun or beautiful.'

  showWarn(){
    let detail='User Deleted a Weco Rule';
    if (this.count++%5===0)
      detail = this.longSentence;
    this.messageService.add({severity:'warn', summary:'User Action', detail: detail});
  }

  showSuccess(){
    let detail = 'Weco Rule 123 Saved';
    if (this.count++%5===0)
      detail = this.longSentence;
    this.messageService.add({severity:'success', summary:'Service Call', detail:detail});
  }

  showError(){
    let detail = 'api-call:get-factories returned 404';
    if (this.count++%5===0)
      detail = this.longSentence;
    this.messageService.add({severity:'error', summary:'Service Call', detail:detail});
  }
}

Если я открываю боковую панель и добавляю в нее несколько сообщений, они появляются, но когда я закрываю и снова открываю, они исчезают. Хотя я вижу, что переменная messages все еще содержит их. Почему?
P.S. Если я затем добавлю еще несколько сообщений, я увижу только новые.

Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
1
0
75
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В боковом меню есть компонент под названием p-messages. Если вы отметите этот элемент, вы заметите, что содержимое p-sidebar уничтожается при закрытии.

Когда вы снова открываете боковую панель, данные остаются прежними, но сообщения уничтожаются.

Я думаю, что компонент p-messages будет показывать только то, что ссылки на массивы изменяются, это может быть связано с тем, что *ngFor внутри компонента имеет trackBy, поэтому нам нужно сбросить каждую ссылку на элементы массива в памяти, чтобы мы обманом заставили p-messages думать, что есть есть новые сообщения в списке, для этого можно использовать деструктуризацию объекта! Я сделаю это, когда откроется боковая панель (onShowNotificationSideBar)

onShowNotificationSideBar() {
    this.notificationSideBarVisible = true;
    this.messages = [...this.messages.map(x => ({...x}))]; // <- creates new references for the array and its contents!
}

полный код

import { Component } from '@angular/core';
import { Message, MessageService } from 'primeng/api';

@Component({
  selector: 'sidebar-basic-demo',
  templateUrl: './sidebar-basic-demo.html',
  providers: [MessageService],
})
export class SidebarBasicDemo {
  title = 'WECO';
  notificationSideBarVisible = false;

  constructor(private messageService: MessageService) {
    messageService.messageObserver.subscribe((m: Message | Message[]) => {
      if (!Array.isArray(m)) {
        this.messages.push(m);
      }
      this.messages = [...this.messages];
    });
  }

  onShowNotificationSideBar() {
    this.notificationSideBarVisible = true;
    this.messages = [...this.messages.map(x => ({...x}))];
  }

  count = 0;

  messages: Message[] = [
    // { severity: 'success', summary: 'Success', detail: 'Message Content' },
    // { severity: 'info', summary: 'Info', detail: 'Message Content' },
    // { severity: 'warn', summary: 'Warning', detail: 'Message Content' },
    // { severity: 'error', summary: 'Error', detail: 'Message Content' }
  ];

  longSentence =
    'Let’s end all this nonsense about how long sentences = run-on sentences. You can have a six-word run-on sentence (“I went shopping I ate donuts.”), while most of the sentences below are much, much longer than that and are not run-ons'; //'And let’s end all this nonsense about how long sentences = run-on sentences. You can have a six-word run-on sentence (“I went shopping I ate donuts.”), while most of the sentences below are much, much longer than that and are not run-ons (except for a few examples like Jose Saramago).  But whether the sentence is grammatically correct isn’t nearly as important as whether the sentence is fun or beautiful.'

  showWarn() {
    let detail = 'User Deleted a Weco Rule';
    if (this.count++ % 5 === 0) detail = this.longSentence;
    this.messageService.add({
      severity: 'warn',
      summary: 'User Action',
      detail: detail,
    });
  }

  showSuccess() {
    let detail = 'Weco Rule 123 Saved';
    if (this.count++ % 5 === 0) detail = this.longSentence;
    this.messageService.add({
      severity: 'success',
      summary: 'Service Call',
      detail: detail,
    });
  }

  showError() {
    let detail = 'api-call:get-factories returned 404';
    if (this.count++ % 5 === 0) detail = this.longSentence;
    this.messageService.add({
      severity: 'error',
      summary: 'Service Call',
      detail: detail,
    });
  }
}

HTML

<div class = "main">
  <button type = "button" (click) = "onShowNotificationSideBar()" label = "Show">
    show sidebar
  </button>
  <p-sidebar
    [(visible)] = "notificationSideBarVisible"
    position = "right"
    [style] = "{width:'50em'}"
  >
    <button
      type = "button"
      pButton
      pRipple
      (click) = "showSuccess()"
      label = "S"
      class = "p-button-success"
    >
      success
    </button>
    <button
      type = "button"
      pButton
      pRipple
      (click) = "showWarn()"
      label = "W"
      class = "p-button-warning"
    >
      warn
    </button>
    <button
      type = "button"
      pButton
      pRipple
      (click) = "showError()"
      label = "E"
      class = "p-button-danger"
    >
      error
    </button>
    <h3>Messages</h3>
    <h5>{{messages}}</h5>
    <p-messages [(value)] = "messages" [enableService] = "false"></p-messages>
  </p-sidebar>
  <p-toast position = "center"></p-toast>
</div>

Демо-версия Stackblitz

Спасибо @Narin, это решило проблему, но мне все равно хотелось бы знать, почему это произошло. Это по какой-то причине намеренное поведение Primeng? Или ошибка?

ILIA BROUDNO 04.04.2024 16:16

@ILIABROUDNO Компонент был создан и уничтожен, обнаружение изменений установлено на OnPush в исходном коде , поэтому нам нужно обновить ссылки на элементы, чтобы обнаружение изменений запускалось внутри p-messages, это моя теория

Naren Murali 04.04.2024 16:19

Другие вопросы по теме