Roteador de interface de usuário angular nested resolução de estado em estados filho

Em um aplicativo angular em que estou trabalhando, gostaria que houvesse um estado pai abstrato que resolvesse certas dependencies para todos os estados de seus filhos. Especificamente, gostaria que todos os estados exigissem que um usuário autenticado herdasse essa dependência de algum estado de authroot.

Eu estou correndo em problemas com a dependência de pai nem sempre sendo re-resolvida. Idealmente, eu gostaria de ter o estado pai verificar se o usuário ainda está conectado para qualquer estado filho automaticamente. Nos documentos , diz

Os estados filhos herdarão dependencies resolvidas do (s) estado (s) pai (s), que podem sobrescrever.

Eu estou achando que a dependência de pai só está sendo re-resolvida se eu entro em qualquer estado de criança de um estado fora do pai, mas não se movendo entre estados de irmão.

Neste exemplo, se você mover entre os estados authroot.testA e authroot.testB, o método GetUser será chamado apenas uma vez. Quando você se move para o other estado e volta, ele será executado novamente.

Eu sou capaz de colocar a dependência do usuário em cada um dos estados filhos para garantir que o método é chamado toda vez que você entra em qualquer um desses estados, mas que parece derrotar o propósito da dependência herdada.

Estou entendendo os documentos incorretamente? Existe uma maneira de forçar o estado pai a resolver novamente suas dependencies, mesmo quando o estado muda entre irmãos?

jsfiddle

       (function(ng) { var app = ng.module("Test", ["ui.router"]); app.config(["$stateProvider", "$urlRouterProvider", function(sp, urp) { urp.otherwise("/testA"); sp.state("authroot", { abstract: true, url: "", template: "
", resolve: {User: ["UserService", function(UserService) { console.log("Resolving dependency..."); return UserService.GetUser(); }]} }); sp.state("authroot.testA", { url: "/testA", template: "

Test A {{User|json}}

", controller: "TestCtrl" }); sp.state("authroot.testB", { url: "/testB", template: "

Test B {{User|json}}

", controller: "TestCtrl" }); sp.state("other", { url: "/other", template: "

Other

", }); }]); app.controller("TestCtrl", ["$scope", "User", function($scope, User) {$scope.User = User;}]); app.factory("UserService", ["$q", "$timeout", function($q, $timeout) { function GetUser() { console.log("Getting User information from server..."); var d = $q.defer(); $timeout(function(){ console.log("Got User info."); d.resolve({UserName:"JohnDoe1", OtherData: "asdf"}); }, 500); return d.promise; }; return { GetUser: GetUser }; }]); })(window.angular); Goto A Goto B Goto Other
Loading...

A maneira que eu acho o roteador ui excepcional, está no comportamento que você acabou de descrever.

Vamos pensar em alguma entidade, por exemplo, contato. Então seria legal ter um lado direito nos mostrando a lista de contatos, a parte esquerda o detalhe. Por favor, verifique o básico sobre o uso do roteador-ui com o AngularJS para obter informações rápidas sobre o layout. Uma citação:

O ui-router abrange totalmente a natureza de máquina de estado de um sistema de roteamento. Ele permite definir estados e fazer a transição de seu aplicativo para esses estados. A verdadeira vitória é que ela permite separar estados nesteds e fazer layouts muito complicados de uma maneira elegante.

Você precisa pensar sobre o seu roteamento de forma um pouco diferente, mas uma vez que você tenha a cabeça em torno da abordagem baseada no estado, eu acho que você vai gostar.

Ok, por que tudo isso?

Porque podemos ter um Contact estado representando uma lista. Diga uma lista fixa da perspectiva do detalhe . (Ignorar lista de paginação de filtragem agora) Podemos clicar na lista e ser movido para um estado Contact.Detail(ID) , para ver apenas o item selecionado. E, em seguida, selecione outro contato / item.

Aqui a vantagem de estados nesteds vem:

A lista (o Contact estado) não é recarregada. Enquanto o estado filho Contact.Detail é.

Isso deve explicar por que o comportamento “estranho” deve ser tratado como correto.

Para responder à sua pergunta, como lidar com o estado do usuário. Eu usaria algum irmão muito superior de um estado de rota, com sua visão separada e controlador e algum ciclo de vida … acionado em alguns ciclos

Real resposta curta é usar:

$rootScope.$on("$stateChangeStart")

para ouvir qualquer alteração no escopo e fazer as ações apropriadas.

Resposta mais longa é, confira o violino: http://jsfiddle.net/jasallen/SZGjN/1/

Observe que usei app.run, o que significa que estou resolvendo o usuário para cada alteração de estado. Se você quiser limitá-lo a alterações de estado enquanto authRoot estiver no parentesco, coloque a verificação de $stateChangeStart no controlador authRoot.