Изменённое свойства в сущности отображается не сразу

verfaa

Профессор
Регистрация
29 Янв 2007
Сообщения
416
Реакции
49
Использую Symfony 6.3.0
На сайте есть тёмная тема и светлая тема.
Соответственно сущность User имеет свойство darkTheme = true || false
В профиле юзера есть настройки, в которых он может изменить тему на светлую или тёмную, кликнув на radio.
Написал для реализации контроллер

Код:
    /**
     * @Route(path="/settings", name=".settings")
     */
    public function settings(Request $request, Handler $handler): Response
    {
        $command = new Command($this->getUser()->getId(), $this->getUser()->getdark_theme());
        
        $form = $this->createForm(Form::class, $command);
        $form->handleRequest($request);
        
        if($form->isSubmitted() && $form->isValid()){
            try {
                $handler->handle($command);
                $this->addFlash("success", "Settings was successfully updated.");
            } catch (\DomainException $e) {
                $this->logger->warning($e->getMessage(), ['exception' => $e]);
                $this->addFlash("error", $e->getMessage());
            }
        }
    
        return $this->render("app/dashboard/user/settings.html.twig", [
            'form' => $form->createView(),
        ]);
    }

Form:
Код:
    class Form extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options): void
        {
            $builder
                ->add("dark_mode", ChoiceType::class, [
                    'choices' => [
                        'Dark Mode' => 1,
                        'Light Mode' => 0,
                    ],
                    'multiple' => false,
                    'expanded' => true,
                ]);
        }
    
        public function configureOptions(OptionsResolver $resolver): void
        {
            $resolver->setDefaults([
                'data_class' => Command::class,
            ]);
        }
    }

Handler, который сохраняет изменённую сущность в БД:
Код:
    class Handler
    {
        private UserRepository $users;
        private Flusher $flusher;
    
        public function __construct(UserRepository $users, Flusher $flusher)
        {
            $this->users = $users;
            $this->flusher = $flusher;
        }
    
        public function handle(Command $command): void
        {
            $user = $this->users->get($command->id);
    
            $user->setDarkTheme(
                (bool)$command->dark_mode
            );
    
            $this->flusher->flush();
        }
    }
И всё работает корректно - настройка меняется. Но проблема визуально состоит в том, что:
Например, у юзера установлена светлая тема и он желает изменить её на тёмную.
Он идёт в настройки, кликает на radio Dark Mode и кликает кнопку Submit. Происходит отправка формы, юзера редиректит на эту же страницу, показывается флеш-сообщение "Settings was successfully updated.". Но тема так и остаётся старой - светлой. А уж если затем перейти на любую другую страницу сайта - появляется уже тёмная тема.
Вопрос: почему так происходит? И как исправить это? (Что бы после сабмита формы сразу появлялась выбранная тема).
 
Проблема, о которой вы говорите, связана с тем, что после отправки формы и обновления настроек пользователя на сервере, вы не обновляете текущую сессию пользователя, чтобы отразить изменения темы. В результате пользователь видит изменения только после перезагрузки страницы или перехода на другую страницу.

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

Код:
public function settings(Request $request, Handler $handler, SessionInterface $session): Response
{
    $command = new Command($this->getUser()->getId(), $this->getUser()->getdark_theme());
    
    $form = $this->createForm(Form::class, $command);
    $form->handleRequest($request);
    
    if ($form->isSubmitted() && $form->isValid()) {
        try {
            $handler->handle($command);
            // Обновление сессии пользователя с новой темой
            $this->getUser()->setDarkTheme((bool) $command->dark_mode);
            $session->set('_locale', $this->getUser());
            $this->addFlash("success", "Settings was successfully updated.");
        } catch (\DomainException $e) {
            $this->logger->warning($e->getMessage(), ['exception' => $e]);
            $this->addFlash("error", $e->getMessage());
        }
    }

    return $this->render("app/dashboard/user/settings.html.twig", [
        'form' => $form->createView(),
    ]);
}

Обратите внимание на строки:

Код:
$this->getUser()->setDarkTheme((bool) $command->dark_mode);
$session->set('_locale', $this->getUser());

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

Чтобы решить эту проблему, вы можете принудительно обновить страницу после успешного обновления настроек, или же обновить состояние темы в сессии (или там, где оно хранится для текущего пользователя) перед рендерингом страницы.
 
Назад
Сверху