Angular — обновить/получить данные после удаления

Я приземлился на проект в полете с использованием Angular, не зная слишком много об Angular. В настоящее время я работаю над простым экраном CRUD. После удаления строки, как я могу «обновить» пользовательский интерфейс? Вот методы внутри моего компонента:

    AATList:IAat[];

confirmDelete(): void{
    //this.myService.deleteAAT(this.satNumber).subscribe(data => {this.AATList = data;});
    //this.myService.deleteAAT(this.satNumber).subscribe(() => {this.getAATtEntries(); });
    this.myService.deleteAAT(this.satNumber).subscribe();
    this.getAatEntries();
    this.modalRef.hide();
}

getAATtEntries() {
    console.info("entries");
    this.myService.getAATList().subscribe(data => {this.AATList = data});
}

(Добавлено при редактировании внутри компонента):

openDeleteModal(template: TemplateRef<any>, satNumber: number) {
    this.satNumber = satNumber;
    this.modalRef = this.modalService.show(template, {class: 'modal-sm'});
  }

Услуги:

getAATList() {
    return this.httpClient.get<ISmt[]>(environment.ApiEndPoint + '/api/SMTDatas', {withCredentials:true});
}

deleteAAT(satNumber : number) {
    return this.httpClient.delete(environment.ApiEndPoint + '/api/SMTDatas/' + satNumber, {withCredentials:true} )
}

(Я использую HttpClient от @angular/common/http для услуг)

Я пробовал первые три строки в методе confirmDelete безрезультатно. Что мне здесь не хватает? Я плохо разбираюсь в Angular, поэтому не стесняйтесь указывать что-то еще.

ОБНОВИТЬ: HTML:

    <a class = "text-danger" data-toggle = "tooltip" data-placement = "top" title = "Delete" (click) = "openDeleteModal(deleteTemplate, smt.SMTNumber)"><i class = "fa fa-trash"></i>Delete</a>
...
    <ng-template #deleteTemplate>
      <div class = "modal-body text-center">
        <p>Are you sure you want to delete this SAT?</p>
        <button type = "button" class = "btn btn-default" (click) = "confirmDelete()" >Yes</button>
        <button type = "button" class = "btn btn-primary" (click) = "denyDelete()" >No</button>
      </div>
    </ng-template>

Я думаю, вы можете подписаться на метод modelRef.hide. Не могли бы вы попробовать это и вызвать метод get при подписке. Как this.modelRef.hide().subscribe(result=>{this.getAATtentries(‌​);});

ZearaeZ 19.02.2019 18:49
getAATList возвращает список ISmt, и вы назначаете его списку IAat в getAATtEntries, у них одинаковые поля?
ElasticCode 19.02.2019 18:58

@ZearaeZ Не похоже, что я могу это сделать. Свойство «подписаться» не существует для типа «пусто»

user94614 20.02.2019 14:37

@WaelAbbas Да, у них одинаковые поля

user94614 20.02.2019 14:37

@ZearaeZ, какой модальный modalRef компонент вы используете?

ElasticCode 20.02.2019 15:04

Просто для справки, я использую import { BsModalService, BsModalRef } from 'ngx-bootstrap/modal';

user94614 20.02.2019 20:17

Вы можете использовать this.modalRef.content.onClose.subscribe(result => { console.info('results', result); }) вот как вы можете поймать событие закрытия для диалога Ngx-Bootstrap.

ZearaeZ 21.02.2019 04:02
Тестирование функциональных 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
3
7
8 366
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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

Примечание. Из-за чувства ответственности я добавил обновленную информацию под постом, чтобы дать немного «лучшее» представление.


TL;DR: Прочтите о подписках и субъектах, а также о том, как установить связь между компонентом и службой. Вы можете добиться того, чего хотите, либо отправив запрос GET после успешного запроса DELETE, либо обновив свой пользовательский интерфейс, локально удалив элемент из списка после успешного запроса DELETE.

Более длинная версия:

Идея может звучать следующим образом:

Если вы вносите изменения, которые хотите увидеть позже (например, 99,9% приложений), вам нужно будет сделать внутренний вызов.

То, как вы обновляете свой пользовательский интерфейс, зависит от того, как вы хотите его продолжить, после того, как вы сделали внутренний вызов.

Итак, рассмотрим случай, когда вы удаляете элемент из списка. Вы отправляете запрос на удаление этого конкретного элемента и получаете ответ от серверной части. Этот ответ должен сообщить вам, была ли выполненная вами операция удаления успешной или нет.

На основании этой информации вы можете

1) найти элемент в списке, перебирая его, и удалить его локально (быстрее)

2) сделайте еще один GET-запрос к серверной части и отобразите обновленный результат после успешного удаления (безопаснее, но в итоге вы делаете 2 запроса для каждой операции).

Как вы могли бы подойти к вопросу «успешно ли удаление» зависит от вашей реализации, но я поделюсь одним из них ниже.

Для этого вам было бы полезно прочитать о Подписки и Предметы с использованием rxjs. Я буду писать, следуя второму варианту, о котором я упоминал выше.

В службе, в которую вы звоните, вы можете создать тему. Вы будете использовать эту тему для уведомления слушателей (т. е. тех, кто подписался на это событие) о любых обновлениях с помощью метода следующий.

В вашем сервисе вы можете создать новую тему следующим образом:

private _deleteOperationSuccessfulEvent$: Subject<boolean> = new Subject();

и создайте для него геттер следующим образом:

get deleteOperationSuccessfulEvent$(): Observable<boolean> {
    return this._deleteOperationSuccessfulEvent$.asObservable();
} 

Когда вы получаете ответ на свой HTTP-запрос DELETE, в зависимости от успеха или неудачи, вы можете выдать значение true или false следующим образом:

this._deleteOperationSuccessfulEvent$.next(true);

Пока что мы выдаем информацию о том, прошла ли операция удаления успешно или нет.

Но его пока никто не слушает. Итак, в вашем компонент вы можете создать подписку:

deleteOperationSuccessfulSubscription: Subscription;

и в вашем методе ngOnInit вы можете подписываться для deleteOperationSuccessfulEvent$, созданного в вашей службе:

this.deleteOperationSuccessfulSubscription = this.yourService.deleteOperationSuccessfulEvent$.subscribe(...stuff will come here...);

(обратите внимание, что мы использовали значение deleteOperationSuccessfulEvent$, а не приватное _deleteOperationSuccessfulEvent$.)

Теперь ваш компонент прослушивает событие удаления вашей службы. Нам просто нужно действовать.

this.deleteOperationSuccessfulSubscription = this.yourService.deleteOperationSuccessfulEvent$
    .subscribe(isSuccessful => {
        if (isSuccessful === true) { 
            make a GET request and display the returning data, following similar steps to which we followed so far 
        } else {
            delete operation was NOT successful, you can display an error or retry etc.
        }
    });

Дайте знать, если у вас появятся вопросы.


Обновлять: Делая все это, следует отметить некоторые вещи с точки зрения Angular и rxjs:

1. Старайтесь не использовать .subscribe() в машинописном коде — вместо этого попробуйте использовать оператор .pipe() для обработки вашей логики. Вместо этого позвольте Angular обрабатывать вашу подписку, используя async pipe в вашем шаблоне. Вы можете добавить .catchError(err => ...) в свой .pipe(), чтобы убедиться, что вы ловите свои ошибки и правильно их обрабатываете.

2- Если вам действительно нужно использовать .subscribe(), не забудьте отписаться от этой подписки в ngOnDestroy() {...}. В противном случае вы рискуете получить утечку памяти в своем приложении.

ngOnDestroy() {
  this.mySubscription.unsubscribe();
} 

Это лучший способ сделать это, если ответ сервера на удаление был успешным и с остальными данными не произошло никаких изменений, то просто удалите их из массива, который заполняется на фронтенде. Нет причин использовать больше ресурсов сервера.

Pari Baker 22.02.2019 00:23

Это очень помогло мне решить, следует ли просто удалить элемент или перезагрузить весь список.

Dr.Legendaddy 22.04.2020 07:47

Обновлено: я думаю, что вы закрываете модальное окно до того, как запрос будет выполнен. Также предполагается, что вы хотите получить список в своем родитель, а не в модальном. Итак, сначала я бы удалил, скрыл модальное окно, прослушал модальное закрытие в родительском элементе и снова извлек список... так что-то вроде:

this.myService.deleteAAT(this.satNumber).subscribe(() => this.modalRef.hide());

Затем в своем родителе послушайте скрытие:

this.modalService.onHide.pipe(
  switchMap(() => this.myService.getAATList())
).subscribe(data => {this.AATList = data})

ОРИГИНАЛ:

Когда вы делаете это:

this.myService.deleteAAT(this.satNumber).subscribe();
this.getAatEntries();

getAatEntries() на самом деле запускается до завершения удаления (скорее всего), поэтому вам нужно связать эти запросы в цепочку, вы можете добиться этого с помощью switchMap:

this.myService.deleteAAT(this.satNumber).pipe(
  switchMap(() => this.myService.getAATList())
)
.subscribe((data: ISmt[]) => this.AATList = data);

ой, подождите, я не увидел закомментированный код, this.myService.deleteAAT(this.satNumber).subscribe(() => {this.getAATtEntries(); });должен работает, но подписываться внутри подписки не рекомендуется. Вы получаете какие-либо ошибки, оба запроса даже запускаются правильно и не выдают ошибку?

AT82 19.02.2019 19:35

Спасибо за ответ. Похоже, что Get не срабатывает внутри подписки на удаление. Никакие ошибки не вылетают. Если я перейду к другой ссылке на странице или обновлю страницу, строка больше не будет видна, а также не возникнет ошибки. Есть ли что-то еще, что вам нужно увидеть в коде? Кроме того, мне пришлось настроить фрагмент кода, добавив скобки внутри switchMap вокруг возврата, но тот же результат: Get не срабатывает в Delete. Есть предположения?

user94614 20.02.2019 14:31

отредактировал мой ответ, теперь я много угадывал, так что это может быть неправильно, если это не поможет, создайте минимальный воспроизводимый пример (что в принципе всегда должно делаться;)) В противном случае помочь невозможно.

AT82 20.02.2019 18:43

Я попробую, и я знаю. Я думал, что это может быть что-то глупое с моей стороны, или мне повезет с одним из ответов :)

user94614 20.02.2019 19:02

Похоже, это удалило и обновило пользовательский интерфейс после того, как я вручную отключил модальное окно. Я добавил дополнительный код, чтобы посмотреть, прояснит ли это что-нибудь. Спасибо за ваше время.

user94614 22.02.2019 16:42

Вы можете использовать событие onHidden для модели (которое срабатывает, когда модальное окно перестало быть скрытым от пользователя), чтобы загрузить ваши данные, как показано ниже.

constructor(private modalService: BsModalService) {
    this.modalService.onHidden.subscribe(() => {
         // Fired when the modal has finished being hidden from the user
        this.getAATtEntries();
    });
}

confirmDelete(): void{
    this.myService.deleteAAT(this.satNumber).subscribe(() => { this.modalRef.hide(); });
}

Это работает (до некоторой степени), но мне нужно щелкнуть модальное окно, чтобы модальное окно скрылось и обновилось. Есть ли что-то еще, что может повлиять на действие скрытия?

user94614 22.02.2019 15:32

@ user94614 не понял вашей точки зрения, можете ли вы рассказать больше о том, что не работает?

ElasticCode 22.02.2019 17:21

Извините, когда я нажимаю «Да» в модальном окне, срабатывает удаление, но получение и модальное окно не скрываются, пока я не нажму за пределами модального окна (в другом месте экрана). Я внес правку, если это что-то проясняет.

user94614 22.02.2019 19:45

@ user94614 куда ты звонишь this.modalRef.hide();?

ElasticCode 22.02.2019 19:50

@user94614 попробуйте добавить this.modalService.setDismissReason('Yes'); перед this.modalRef.hide();

ElasticCode 22.02.2019 20:19

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