Jak przekazać obiekt do stanu za pomocą routera UI?

119

Chciałbym móc przejść do stanu i przekazać dowolny obiekt za pomocą routera ui.

Zwykle jestem tego świadomy $stateParams jest używany, ale uważam, że ta wartość jest wstawiana do adresu URL i nie chcę, aby użytkownicy mogli dodawać te dane do zakładek.

Chciałbym zrobić coś takiego.

$state.transitionTo('newState', {myObj: {foo: 'bar'}});

function myCtrl($stateParams) {
   console.log($stateParams.myObj); // -> {foo: 'bar'}
};

Czy można to zrobić bez kodowania wartości w adresie URL?

eddiec
źródło
1
Mechanizmy ui-routera zachowują stany adresu URL podczas nawigacji. Tak więc, jeśli użytkownik odświeża stronę, wraca na stronę, na której był. Jeśli nie chcesz używać tego zachowania, rozważ użycie innych mechanizmów (nieprzetworzone funkcje w kontrolerze / dyrektywach itp.) I użyj plików cookie / przechowywanie do przechowywania danych tymczasowych
Neozaru
Może użyj localStorage z adresem URL jako kluczem do danych?
Neil
2
Skąd się biorą wartości? Ui.router ma koncepcję „rozwiązania”, aby załadować dane do zakresu przed przejściem do żądanego stanu. Podobnie istnieją metody onEnter i onExit. Ponadto możesz użyć pamięci lokalnej.
Josh C.
Jak @JoshC. wspomniany, brzmi, jakbyś chciał przyjrzeć się rozwiązaniu danych przed przejściem do stanu. github.com/angular-ui/ui-router/wiki#resolve
TrazeK
Zobacz odpowiedź stackOverlord, jak to zrobić oficjalnie.
AlikElzin-kilaka

Odpowiedzi:

163

W wersji 0.2.13 powinieneś móc przekazywać obiekty do $ state.go,

$state.go('myState', {myParam: {some: 'thing'}})

$stateProvider.state('myState', {
                url: '/myState/{myParam:json}',
                params: {myParam: null}, ...

a następnie uzyskaj dostęp do parametru w kontrolerze.

$stateParams.myParam //should be {some: 'thing'}

myParam nie pojawi się w adresie URL.

Źródło:

Zobacz komentarz christopherthielena https://github.com/angular-ui/ui-router/issues/983 , reprodukowany tutaj dla wygody:

christopherthielen: Tak, to powinno działać teraz w wersji 0.2.13.

.state ('foo', {url: '/ foo /: param1? param2', params: {param3: null} // null jest wartością domyślną});

$ state.go ('foo', {param1: 'bar', param2: 'baz', param3: {id: 35, name: 'what'}});

$ stateParams w 'foo' to teraz {param1: 'bar', param2: 'baz', param3: {id: 35, name: 'what'}}

url to / foo / bar? param2 = baz.

stackOverlord
źródło
Działa transitionTorównież z.
AlikElzin-kilaka
13
Muszę coś robić źle: - / Jestem na 0.2.13, ale jeśli spróbuję przejść i sprzeciwić się, wychodzi w stanie jako ciąg[object Object]
ErichBSchulz
15
@ErichBSchulz Chociaż nie jest to uwzględnione w tej odpowiedzi, sztuczka umożliwiająca wykonanie tego zadania polega na dołączeniu nazwy parametru do ciągu adresu URL stanu i określeniu typu jako JSON. dawny. $stateProvider.state('myState', { url: '/myState/{myParam:json}', params: {myParam: null},...Zobacz uwagi do wydania 0.2.13 i komentarze do kodu dla tej funkcji.
Syon
1
Miałem parametr id w moim adresie URL i musiałem dodać go również do obiektu params. { url: '/mystate/{id:[0-9]+}', params: { id: null, myParam: null }, ...
GraehamF
3
Musi być jakaś czarna magia - cały mój json pokazuje adres URL: (((
Kabachok
25

Istnieją dwie części tego problemu

1) przy użyciu parametru, który nie zmieniłby adresu URL (przy użyciu właściwości params):

$stateProvider
    .state('login', {
        params: [
            'toStateName',
            'toParamsJson'
        ],
        templateUrl: 'partials/login/Login.html'
    })

2) przekazanie obiektu jako parametru: Cóż, nie ma bezpośredniego sposobu, jak to zrobić teraz, ponieważ każdy parametr jest konwertowany na ciąg ( EDIT : od 0.2.13, to już nie jest prawdą - możesz używać obiektów bezpośrednio), ale możesz to obejść, tworząc samodzielnie łańcuch

toParamsJson = JSON.stringify(toStateParams);

iw kontrolerze docelowym ponownie zdeserializuj obiekt

originalParams = JSON.parse($stateParams.toParamsJson);
Svatopluk Ledl
źródło
1
Właściwie do mijania obiektów to całkiem niezły hack :)
Tek
możemy przekazać obiekt bezpośrednio. sprawdź zaakceptowaną odpowiedź
Kishore Relangi
20

Właściwie możesz to zrobić.

$state.go("state-name", {param-name: param-value}, {location: false, inherit: false});

To jest oficjalna dokumentacja dotycząca opcji w state.go

Wszystko jest tam opisane i jak widać jest to sposób na zrobienie tego.

Tek
źródło
Wypróbowałem dokładnie ten kod i obiekt nie jest zachowany.
Virmundi
1
nie możesz przekazywać obiektów, możesz przekazywać tylko wartości pojedynczych parametrów ... uczynisz to jako obiekt, musisz umieścić wszystkie właściwości jako różne parametry adresu URL. Twórcy Angular-ui-router wciąż pracują nad przekazaniem całego obiektu. Właściwie to chłopaki Svatopluk Ledl podali fajne rozwiązanie. Po prostu utwórz obiekt jako cały ciąg json, a następnie przeanalizuj go. :)
Tek
13

Przy okazji możesz również użyć atrybutu ui-sref w swoich szablonach do przekazywania obiektów

ui-sref="myState({ myParam: myObject })"
Obrabować
źródło
1
Jak otrzymujemy ten obiekt w .state
Shubham,
@Shubham, skonfigurowałbyś „parametry” dla stanu, który otrzyma obiekt, a następnie użyj $ stateParams do pobrania tego obiektu. szczegółowe informacje można znaleźć w dokumentacji angular-ui.github.io/ui-router/site/#/api/… .
tao
to działa, ale nie może zachować danych po odświeżeniu strony.
tao
9

1)

$stateProvider
        .state('app.example1', {
                url: '/example',
                views: {
                    'menuContent': {
                        templateUrl: 'templates/example.html',
                        controller: 'ExampleCtrl'
                    }
                }
            })
            .state('app.example2', {
                url: '/example2/:object',
                views: {
                    'menuContent': {
                        templateUrl: 'templates/example2.html',
                        controller: 'Example2Ctrl'
                    }
                }
            })

2)

.controller('ExampleCtrl', function ($state, $scope, UserService) {


        $scope.goExample2 = function (obj) {

            $state.go("app.example2", {object: JSON.stringify(obj)});
        }

    })
    .controller('Example2Ctrl', function ($state, $scope, $stateParams) {

        console.log(JSON.parse($state.params.object));


    })
vrbsm
źródło
3

Nie, adres URL będzie zawsze aktualizowany po przekazaniu parametrów transitionTo.

Dzieje się tak na state.js: 698 w routerze ui .

popołudnie
źródło