Como passar um objeto para um estado usando o roteador da interface do usuário?

119

Eu gostaria de poder fazer a transição para um estado e passar um objeto arbitrário usando o ui-router.

Estou ciente de que geralmente $stateParamsé usado, mas acredito que esse valor seja inserido no URL e não quero que os usuários possam marcar esses dados como favoritos.

Eu gostaria de fazer algo assim.

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

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

Existe uma maneira de fazer isso sem codificar valores no URL?

eddiec
fonte
1
Os mecanismos do ui-router preservam os estados da URL na navegação. Portanto, se um usuário atualiza a página, ele volta à página em que estava. Se você não quiser usar esse comportamento, considere usar outros mecanismos (funções brutas em seu controlador / diretivas etc.) e use cookies / armazenamento para armazenamento de dados temporários
Neozaru
Use localStorage com o URL como a chave para seus dados, talvez?
4194 Neil
2
De onde vêm os valores? O Ui.router tem o conceito de "resolução" para carregar dados em um escopo antes de fazer a transição para o estado solicitado. Da mesma forma, existem métodos onEnter e onExit. Além disso, você pode usar o armazenamento local.
13134 Josh C.
Como @ JoshC. mencionado, parece que talvez você queira pesquisar dados antes de passar para um estado. github.com/angular-ui/ui-router/wiki#resolve
TrazeK
Veja a resposta do stackOverlord como fazê-lo oficialmente.
AlikElzin-kilaka

Respostas:

163

Na versão 0.2.13, você deve poder passar objetos para $ state.go,

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

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

e, em seguida, acesse o parâmetro no seu controlador.

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

myParam não aparecerá no URL.

Fonte:

Veja o comentário de christopherthielen https://github.com/angular-ui/ui-router/issues/983 , reproduzido aqui por conveniência:

christopherthielen: Sim, isso deve estar funcionando agora em 0.2.13.

.state ('foo', {url: '/ foo /: param1? param2', parâmetros: {param3: null} // null é o valor padrão});

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

$ stateParams em 'foo' agora é {param1: 'bar', param2: 'baz', param3: {id: 35, nome: 'what'}}

url é / foo / bar? param2 = baz.

stackOverlord
fonte
Funciona com transitionTotambém.
AlikElzin-kilaka
13
Eu devo estar fazendo algo errado: - / Eu estou no 0.2.13, mas se eu tentar passar e objeto se trata o no estado como a string[object Object]
ErichBSchulz
15
@ErichBSchulz Embora não esteja incluído nesta resposta, o truque para fazer isso funcionar é incluir o nome do parâmetro na string de URL do estado e especificar o tipo como JSON. ex. $stateProvider.state('myState', { url: '/myState/{myParam:json}', params: {myParam: null},...Veja as notas da versão 0.2.13 e os comentários do código para esse recurso.
Syon
1
Eu tinha um parâmetro id na minha URL e também precisava adicioná-lo ao objeto params. { url: '/mystate/{id:[0-9]+}', params: { id: null, myParam: null }, ...
GraehamF
3
Deve haver alguma magia negra em jogo - toda a minha json está mostrando a url: (((
Kabachok
25

Existem duas partes desse problema

1) usando um parâmetro que não alteraria um URL (usando a propriedade params):

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

2) passando um objeto como parâmetro: Bem, não há maneira direta de como fazê-lo agora, pois todos os parâmetros são convertidos em string ( EDIT : desde 0.2.13, isso não é mais verdade - você pode usar objetos diretamente), mas você pode contornar isso criando a string por conta própria

toParamsJson = JSON.stringify(toStateParams);

e no controlador de destino desserializar o objeto novamente

originalParams = JSON.parse($stateParams.toParamsJson);
Svatopluk Ledl
fonte
1
Na verdade, para passar objetos Isto é bastante um bom corte :)
Tek
nós podemos passar o objeto diretamente. verifique a resposta aceita
Kishore Relangi 13/08/2015
20

Na verdade você pode fazer isso.

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

Esta é a documentação oficial sobre as opções no state.go

Tudo está descrito lá e, como você pode ver, este é o caminho a ser feito.

Tek
fonte
Eu tentei esse código exato e o objeto não é preservado.
Virmundi 31/10
1
você não pode passar objetos, só pode passar valores de parâmetro único .... Para torná-lo um objeto, você deve colocar todas as propriedades como parâmetros de URL diferentes. Os desenvolvedores de angular-ui-router ainda estão trabalhando na passagem do objeto inteiro. Na verdade, aqueles caras Svatopluk Ledl deram uma boa solução. Basta criar o objeto como uma string json inteira e depois analisá-lo. :)
Tek
13

Aliás, você também pode usar o atributo ui-sref em seus modelos para passar objetos

ui-sref="myState({ myParam: myObject })"
Roubar
fonte
1
Como recebemos este objeto no .state
Shubham
@Shubham, você configuraria os 'parâmetros' para o estado que receberá o objeto, usando $ stateParams para recuperar esse objeto. consulte o documento angular-ui.github.io/ui-router/site/#/api/… para obter detalhes.
tao 16/05
isso funciona, mas não é possível manter os dados após a atualização da página.
tao 16/05
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
fonte