Подтвердить что ты не робот

Как сохранить необязательный параметр состояния в браузере в ui-router?

У меня есть одно родительское состояние с двумя дочерними состояниями, внутри которого я собираюсь показать одно состояние на основе URL.

Из этих двух states нужно иметь такие параметры, как param1 и param2, я использую параметр params для определения внутреннего определения ui-router.

Государство

$stateProvider.state('tabs.account', {
    url: '/account',
    views: {
        '[email protected]': {
            templateUrl: 'account.html',
            controller: function($scope, $stateParams) {
                //This params are internally used to make ajax and show some data.
                $scope.param1 = $stateParams.param1;
                $scope.param2 = $stateParams.param2;
            },
        }
    },
    params: {
        param1: { value: null }, //this are optional param
        param2: { value: null } //because they are not used in url
    }
});

Если вы посмотрите на мой маршрут, параметр params действительно не представлен внутри URL, поэтому я рассматриваю его как необязательный.

Проблема

Посмотрите на plunkr, я показал две вкладки Аккаунт и Обзор,

  • Перейдите на вкладку "Съемка", затем добавьте некоторые данные в отображаемый textarea.
  • Нажмите Перейти к Аккаунту, который будет передавать те значения textarea, чтобы на другой вкладке Аккаунт, выполнив ui-sref="tabs.account({param1: thing1, param2: thing2})" на якоре

  • Теперь вы увидите значения param1 и param2 в html, которые были назначены для области с $stateParams

  • Теперь снова нажмите вкладку Обследование, вы попадете на страницу опроса.
  • Просто нажмите кнопку "Назад", вы заметите, что значение param не получает null.

Проблема Plunkr

Я считаю, что у вас есть то, что я хотел спросить, почему необязательное значение параметра не было в магазине? поскольку они были частью государства.

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

  • Создав одну службу, которая будет обмениваться данными между двумя видами.
  • Добавление параметра в URL состояния. вроде url: '/account/:param1/:param2', (Но я бы этого не хотел)

Я уже пробовал angular -ui-routers sticky states, но это, похоже, не работает для меня. Каков лучший способ этого?

Есть ли способ, с помощью которого я могу использовать мой прецедент, любые идеи будут оценены.

Github Ссылка на проблему здесь

4b9b3361

Ответ 1

Я переместил бы определение params в родительское состояние, чтобы разделить необязательные параметры состояния между двумя вашими дочерними состояниями.

Дочерние состояния наследуют $stateParams от вашего родителя, так как нет реального "обходного пути".

Просто введите $stateParams, как обычно, в дочерние контроллеры, и у вас будет полный доступ к параметрам, которые будут переданы. Если вы не хотите использовать параметры в определенном дочернем состоянии, просто не вводите их.

Это работает;

  • Кнопка "Назад"
  • Кнопка прямого доступа
  • ui-sref (без параметров (будет сохраняться как есть))
  • ui-sref (с параметрами (будет перезаписано))

$stateProvider
  .state('parent', {
    params: { p1: null, p2: null }
  })
  .state('parent.childOne', {
    url: '/one',
    controller: function ($stateParams) {
      console.log($stateParams); // { p1: null, p2: null }
    }
  })
  .state('parent.childTwo', {
    url: '/two',
    controller: function ($stateParams) {
      console.log($stateParams); // { p1: null, p2: null }
    }
  })

Если вы в любой момент хотите очистить параметры во время перемещения в дереве состояний parent, вам нужно будет сделать это вручную.

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

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

обновленный плункер

Ответ 2

Решение

Здесь основная логика с использованием в качестве кеша с рабочим Plunker :

Когда вы входите в состояние tabs.account, проверьте свои параметры состояния Если у вас есть их, кешируйте их в локальное хранилище Если вы этого не сделаете, загрузите их из локального хранилища в $stateParams

Вот пример фрагмента кода для справки (взятый из Plunker):

  $stateProvider.state('tabs.account', {
    ...
    onEnter: ['$stateParams', '$window', function($stateParams, $window) {
      if($stateParams.param1) {
        $window.localStorage.setItem('tabs.account.param1', $stateParams.param1);
      } else {
        $stateParams.param1 = $window.localStorage.getItem('tabs.account.param1');
      }
      if($stateParams.param2) {
        $window.localStorage.setItem('tabs.account.param2', $stateParams.param2);
      } else {
        $stateParams.param2 = $window.localStorage.getItem('tabs.account.param2');
      }
    }],
    ...
  }

Ответ 3

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

Задняя панель браузера просто сохраняет историю URL. Он не имеет понятия о внутренних состояниях ui-router и просто заставит URL-адрес измениться.

Принудительное изменение URL-адреса приведет к запуску внутренней машины ui-router, но, к сожалению, ui-router увидит изменение URL-адреса так же, как если бы кто-то изменил URL-адрес вручную.

Ui-router отправит новое изменение маршрута на маршрут, указанный URL. Это означает, что он не знает, что вы хотите "вернуться" и просто измените состояние на новое без каких-либо параметров.

Резюме

Нажатие на кнопку "Назад" приведет к смене состояния в состояние новое в соответствии с URL-адресом вместо возврата в предыдущее состояние.

Вот почему добавление параметров в URL-адрес решает проблему. Поскольку URL-адрес является дискриминационным, вы, наконец, приземлитесь на желаемое состояние.

Надеюсь, это помогло.

Ответ 4

Для меня это звучит как проблема X Y. Предлагаются способы сделать постоянные состояния постоянными, тогда как проблема находится вне этой поверхности.

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

Липкие состояния легко подходят для этого подхода, поскольку он позволяет сохранять DOM и $scope, пока другое состояние активно. Но это не имеет ничего общего с государственными параметрами, когда государство возобновляется.