Проблема обновления пользовательского интерфейса, хотя правильные данные в полезной нагрузке ngrx - PullRequest
0 голосов
/ 31 марта 2020

Я пытался обновить интерфейс в последние дни и не могу найти решение ..

Сценарий: Я хочу иметь возможность редактировать событие из компонент события-редактирования, а затем будет перенаправлен обратно к тому же событию в компоненте события-детали, когда обновление будет выполнено. Я могу внести изменения в бэкэнд, и состояние ngrx показывает мне правильные данные в Redux DevTools. Проблема в том, что когда я нажимаю кнопку update и перенаправляется на подробности события, я вижу старую версию события, пока не обновлю sh страницу. Почему все работает так, как должно, только когда я нажимаю f5?

Спасибо ..

Компонент детали события (где я должен увидеть обновленное событие)

import { Component, OnInit, ChangeDetectionStrategy, OnDestroy, ViewEncapsulation} from 
'@angular/core';

import { AppState } from 'src/app/core/state';
import { Store, select } from '@ngrx/store';
import * as fromEvents from '../../state/events';
import { Observable, Subscription } from 'rxjs';
import { Event } from 'src/app/shared/models';

import { ActivatedRoute } from '@angular/router';
import { AlertifyService } from 'src/app/core/services/alertify.service';

import * as fromSession from '../../../core/state/session';

@Component({
  selector: 'ex-event-detail',
  templateUrl: './event-detail.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
  styleUrls: ['./event-detail.component.scss'],
  encapsulation: ViewEncapsulation.None
})
export class EventDetailComponent implements OnInit, OnDestroy {
  subscription: Subscription;
  eventId: any;
  ev$: Observable<Event>;
  eventUsers$: any;
  userId: number;

  constructor(
    private store$: Store<AppState>,
    private alertify: AlertifyService,
    private activatedRoute: ActivatedRoute,
  ) {
    this.store$.select(fromSession.selectUser).subscribe(user => (this.userId = user.id));
  }

  ngOnInit() {
    this.subscription = this.activatedRoute.params.subscribe(params => {
      this.eventId = params['id'];
    });
    this.loadEvent();
  }

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

  loadEvent() {
    this.store$.dispatch(new fromEvents.LoadEvent(+this.eventId));
    this.ev$ = this.store$.pipe(select(fromEvents.getCurrentEvent));

    this.eventUsers$ = this.store$.pipe(select(fromEvents.getCurrentUsers));
    console.log(this.ev$);
  }
}

Компонент редактирования события (Где я редактирую событие)

import { Component, OnInit, ChangeDetectionStrategy, OnDestroy, ChangeDetectorRef } from '@angular/core';

import { Store, select } from '@ngrx/store';
import { AppState } from 'src/app/core/state';
import { Observable} from 'rxjs';
import { Event } from 'src/app/shared/models';
import * as fromEvents from '../../state/events';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';

@Component({
  selector: 'ex-event-edit',
  templateUrl: './event-edit.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
  styleUrls: ['./event-edit.component.scss']
})
export class EventEditComponent implements OnInit, OnDestroy {
  ev$: Observable<Event>;
  eventEditForm: FormGroup;

  constructor(private store$: Store<AppState>, private fb: FormBuilder) {}

  ngOnInit() {
    this.ev$ = this.store$.pipe(select(fromEvents.getCurrentEvent));

    this.createEventEditForm();
  }

  ngOnDestroy() {}

  createEventEditForm() {
    this.ev$.subscribe(ev => {
      this.eventEditForm = this.fb.group({
        id: [ev.id],
        title: [ev.title, Validators.required],
        description: [ev.description, Validators.required],
        image: [ev.image],
        location: [ev.location, Validators.required],
        startdate: [ev.startDate],
        starttime: [ev.startDate],
        enddate: [ev.endDate],
        endtime: [ev.endDate]
      });
    });
  }

  updateEvent() {
    if (this.eventEditForm.valid) {

      const ev = Object.assign({}, this.eventEditForm.value);
      this.store$.dispatch(new fromEvents.UpdateEvent(ev));
    }
  }
}

И это код для состояния

/*--------------UpdateEventActions--------------*/ 

export class UpdateEvent implements Action {
  readonly type = ActionTypes.UPDATE_EVENT;

  constructor(public payload: Event) {}
}

export class UpdateEventSuccess implements Action {
  readonly type = ActionTypes.UPDATE_EVENT_SUCCESS;

  constructor(public payload: Update<Event>) {}
}

export class UpdateEventError implements Action {
  readonly type = ActionTypes.UPDATE_EVENT_ERROR;

  constructor(public payload: string) {}
}


/*--------------UpdateEffect--------------*/ 

@Effect()
  updateEvent$: Observable<Action> = this.actions$.pipe(
    ofType<eventsActions.UpdateEvent>(eventsActions.ActionTypes.UPDATE_EVENT),
    map((action: eventsActions.UpdateEvent) => action.payload),
    switchMap((event: Event) =>
      this.eventResource.updateEvent(event).pipe(
        map(
          (updatedEvent: Event) =>
            new eventsActions.UpdateEventSuccess({
              id: updatedEvent.id,
              changes: updatedEvent
            })
        ), 
        tap(() => this.router.navigate(['/event/' + event.id])),
        catchError(err => of(new eventsActions.UpdateEventError(err)))
      )
    )
  );

/*--------------UpdateReducer--------------*/ 
case eventsActions.ActionTypes.UPDATE_EVENT_SUCCESS: {
      return adapter.updateOne(action.payload, state);
    }

    case eventsActions.ActionTypes.UPDATE_EVENT_ERROR: {
      return {
        ...state,
        error: action.payload
      };
    }

/*--------------UpdateSelectors--------------*/ 

import { createSelector } from '@ngrx/store';

import { AppState } from '../../../core/state';
import { adapter } from './events.adapter';

const { selectAll } = adapter.getSelectors();

export const selectState = (state: AppState) => state.event.evs;

export const getEvents = createSelector(selectState, selectAll )

export const getEventsLoading = createSelector(selectState, state => state.loading);

export const getEventsLoaded = createSelector(selectState, state => state.loaded);

export const getError = createSelector(selectState, state => state.error);

export const getCurrentEventId = createSelector(selectState, state => state.selectedEventId);

export const getCurrentEvent = createSelector(selectState, getCurrentEventId, state => state.entities[state.selectedEventId]); //this is the one i use to list the specific event

export const getCurrentUsers = createSelector(selectState, getCurrentEventId, state => state.users);

1 Ответ

0 голосов
/ 01 апреля 2020

Можете ли вы предоставить код, где вы меняете selectedEventId? В приведенном выше коде я вижу все, кроме места, где поле было обновлено, и я предполагаю, что это может быть ответом на ваш вопрос.

...