2015-09-10 10 views
12

Mam stan z opcjonalnym parametrem zapytania. Myślałem, że to działa dobrze, ale odkryłem, że po określeniu opcjonalnego parametru, jest on zachowywany od tego momentu, gdy przechodzę do tego samego stanu z innymi parametrami, chyba że opcjonalny parametr zostanie jawnie usunięty.Jak usunąć wcześniej podany opcjonalny parametr podczas zmiany stanu z urządzeniem wielofunkcyjnym

Czy istnieje sposób, aby upewnić się, że opcjonalny parametr jest usuwany między zmianami stanu?

To jest przykład tego, jak chcę zmienić stan (test a i test b), ale okazuje się, że muszę użyć wersji "test d" z powodu zachowania parametru opcjonalnego, jeśli został użyty poprzednio.

<a ui-sref="test({req: 'a'})">test a</a><br/> 
<a ui-sref="test({req: 'b'})">test b</a><br/> 
<a ui-sref="test({req: 'c', opt: 'here'})">test c and opt</a><br/> 
<a ui-sref="test({req: 'd', opt: undefined})">test d and explicity without opt</a> 

Jest to podobne do tego, jak mój stan jest skonfigurowany:

 $stateProvider.state('test', { 
      url: '/{req}?opt', 
      params: { 
       opt: {value: null, squash: true} 
      }, 
      template: '<h1>req = {{req}}</h1>' + 
        '<h1>opt = {{opt}}</h1>', 
      controller: function($scope, $stateParams) { 
       $scope.req = $stateParams.req; 
       $scope.opt = $stateParams.opt; 
      } 
     }) 

Oto jsfiddle. Kliknij dwa pierwsze łącza i działa zgodnie z oczekiwaniami, ale po kliknięciu trzeciego linku, a następnie kliknięciu jednego z dwóch pierwszych łączy, zobaczysz, że parametr opcjonalny został zachowany, mimo że został pominięty w pierwsze dwa łącza.

Wolałbym, aby nie trzeba było jawnie resetować opcjonalnego parametru, i faktycznie działa tak, jak to jest opcjonalne.

Wszelkie pomysły? Czy to jest tak zaprojektowane, aby działało? Jeśli tak, to czy istnieje sposób, aby zmusić go do działania tak, jak chcę? Czy znalazłem błąd?

Aktualizacja

Wydaje się, że zachowując opcjonalnego param jest „zaprojektowany jako” oparte na jednym z poniższych odpowiedzi. Nadal jednak w miarę możliwości rozważam skuteczne obejście tego problemu. Przechodzę do stanu z wielu miejsc w mojej aplikacji, a 99% z nich nie określa opcjonalnego parametru. Wolałbym nie modyfikować wszystkich tych przejść i nie informować ich o opcjonalnym parametrze, a zamiast tego określać opcjonalny parametr jako 1% czasu, którego potrzebuję.

Próbowałem utworzyć dwa stany "test" i dziecko "test.opt", a następnie przejść do "testu" normalnie (tj. "Test a" i "test b"), a tylko przejście do "test" test.opt ", gdy określam opcjonalny parametr. Jednak mam postanowienie, które wywołuje reszta i musi wiedzieć, czy parametr opt jest ustawiony, więc to nie działa, ponieważ postanowienie nie może uzyskać dostępu do "opt" od dziecka.

Aktualizacja # 2

Ja również próbowałem czyniąc duplikat „test” stanie, nazwany „testopt” w takim przypadku jedyną różnicą jest? Zdecydować parametr. Jednak najwyraźniej ui-router nie może rozróżnić dwóch adresów URL, które różnią się tylko paramem zapytania, i dlatego nadal próbuje przejść do "testu", nawet jeśli parametr opt jest częścią adresu URL.

+0

Wydaje się prosicie o to http://stackoverflow.com/questions/31542972/how-to-persist-optional-parameter-on-browser-back -in-ui-router I jest błąd rejestrowany przeciwko temu samemu https://github.com/angular-ui/ui-router/issues/2115 –

+0

Nie sądzę, że jest to ten sam problem. Pytanie dotyczyło zachowania opcjonalnego parametru, więc "powrót" działa zgodnie z oczekiwaniami. Mój problem polega na tym, że jest on zachowywany, nawet podczas nawigacji do nowego stanu. Omawiane rozwiązanie tego błędu polega na buforowaniu stanów, aby były dostępne po przejściu "wstecz". Ponadto, jak widzisz, w rzeczywistości używam paramatu na url, który jest nieco inny. Rozwiązanie problemu SO mówi, że muszę ręcznie usunąć parametr, który staram się znaleźć alternatywę dla. – DavidA

Odpowiedz

19

Wystarczy dodać opcję UI-sref-opts z dziedziczą = false do linków:

<a ui-sref="test({req: 'a'})" ui-sref-opts="{inherit: false}">test a</a><br/> 
<a ui-sref="test({req: 'b'})" ui-sref-opts="{inherit: false}">test b</a><br/> 
<a ui-sref="test({req: 'c', opt: 'here'})" ui-sref-opts="{inherit: false}">test c and opt</a><br/> 
<a ui-sref="test({req: 'd', opt: undefined})" ui-sref-opts="{inherit: false}">test d and explicity without opt</a> 

wątku, który dokumentuje tę funkcję nr wniosek i realizacja: https://github.com/angular-ui/ui-router/issues/376

---- EDIT --- -

Ponieważ powyższe rozwiązanie nie wydaje się idealne, ponieważ wymaga również aktualizacji (i utrzymania) każdej z kotew ui-trenowania w celu ustawienia pożądanego zachowania, innym rozwiązaniem może być zastąpienie metody go(...) e inherit domyślnie opcja false. Chociaż nie jestem pewien, czy jest to zalecane wzór, aby to zrobić, zmienić .config do następujących:

.config(['$stateProvider', '$provide', function ($stateProvider, $provide) { 
    $stateProvider.state('test', { 
     url: '/{req}?opt', 
     params: { 
      opt: {value: null, squash: true} 
     }, 
     template: '<h1>req = {{req}}</h1>' + 
      '<h1>opt = {{opt}}</h1>', 
     controller: function($scope, $stateParams) { 
      $scope.req = $stateParams.req; 
      $scope.opt = $stateParams.opt; 
     } 
    }); 

    $provide.decorator('$state', function ($delegate) { 
     var state = $delegate; 

     state.baseGo = state.go; 

     var go = function (to, params, options) { 
      options = options || {}; 

      if (angular.isUndefined(options.inherit)) { 
       options.inherit = false; 
      } 

      this.baseGo(to, params, options); 
     }; 

     state.go = go; 
     return $delegate; 
    }); 
}]) 
+0

Jest to opcja, ale nie różni się zbytnio od ustawienia opcji opt na undefined, jak w 'test d'. Sytuacja jest taka, że ​​99% moich linków jest pierwszego typu, a tylko jedno miejsce używa opcjonalnej wartości. Nie chcę, aby wszystkie 99% pozostałych lokalizacji uwzględniało opcjonalny parametr, jeśli to możliwe. – DavidA

+0

Proszę zobaczyć moją zaktualizowaną odpowiedź. – GPicazo

+0

To jest znacznie bliższe temu, co chcę, * prawie * dokładnie. Istnieją jednak dwa problemy. Po pierwsze, wygląda na to, że opcje options.inherit są ustawione domyślnie, więc sprawdzenie, czy jest niezdefiniowane, zawsze kończy się niepowodzeniem. Jednak nawet jeśli zmusiłbym to do fałszu tutaj. Linki tworzone przez ui-sref nadal zawierają dziedziczony parametr. Nawigacja działa poprawnie, ale jeśli użytkownik kliknie prawym przyciskiem myszy i "zapisz link", będzie tam dostępny parametr. Dzięki za pomoc i sugestie. – DavidA

5

miałem ten sam problem, z powodu spadku parametrów domyślnych ... Aby zakończyć poprzednia odbiera, syntaxe dla JS zaproszenia jest:

$state.go('new state', {pararemeters... } , {inherit:false});