Pergunta

Estou fazendo uma pergunta semelhante a esta pergunta: Visualizações condicionais da interface do usuário do roteador da interface do usuário?, mas minha situação é um pouco mais complexa e não consigo fazer a resposta fornecida funcionar.

Basicamente, tenho uma url que pode ser renderizada de duas maneiras muito diferentes, dependendo do tipo de entidade para a qual a url aponta.

Aqui está o que estou tentando atualmente

    $stateProvider
        .state('home', {
            url : '/{id}',
            resolve: {
                entity: function($stateParams, RestService) {
                    return RestService.getEntity($stateParams.id);
                }
            },
            template: 'Home Template <ui-view></ui-view>',
            onEnter: function($state, entity) {
                if (entity.Type == 'first') {
                    $state.transitionTo('home.first');
                } else {
                    $state.transitionTo('home.second');
                }
            }
        })
        .state('home.first', {
            url: '',
            templateUrl: 'first.html',
            controller: 'FirstController'
        })
        .state('home.second', {
            url: '',
            templateUrl: 'second.html',
            controller: 'SecondController'
        });

Configurei um Resolve para buscar a entidade real de um serviço tranquilo.Tudo parece estar funcionando até que eu chegue ao transactionTo com base no tipo.

A transição parece funcionar, exceto que a resolução é acionada novamente e o getEntity falha porque o ID é nulo.

Tentei enviar o ID para as chamadas transactionTo, mas ele ainda tenta fazer uma segunda resolução, o que significa que a entidade é buscada duas vezes no serviço restante.

O que parece estar acontecendo é que no manipulador onEnter, o estado ainda não mudou, então, quando a transição acontece, ele pensa que está fazendo a transição para um estado totalmente novo, em vez de para um estado filho.Isso fica ainda mais evidenciado porque quando eu removo a entidade.do nome do estado na transição para, ele acredita que o estado atual é raiz, e não inicial.Isso também me impede de usar 'go' em vez de transactionTo.

Alguma ideia?

Foi útil?

Solução

O modeloUrl também pode ser uma função, para que você verifique o tipo e retorne uma visualização diferente e defina o controlador na visualização, em vez de como parte da configuração do estado.Você não pode injetar parâmetros em templateUrl, então talvez seja necessário usar templateProvider.

$stateProvider.state('home', {
  templateProvider: ['$stateParams', 'restService' , function ($stateParams, restService) {
    restService.getEntity($stateParams.id).then(function(entity) {
        if (entity.Type == 'first') {
              return '<div ng-include="first.html"></div>;
        } else {
              return '<div ng-include="second.html"></div>';
        }
    });
  }]
})

Outras dicas

Você também pode fazer o seguinte:

$stateProvider
        .state('home', {
            url : '/{id}',
            resolve: {
                entity: function($stateParams, RestService) {
                    return RestService.getEntity($stateParams.id);
                }
            },
            template: 'Home Template <ui-view></ui-view>',
            onEnter: function($state, entity) {
                if (entity.Type == 'first') {
                    $timeout(function() {
                            $state.go('home.first');
                        }, 0);
                } else {
                    $timeout(function() {
                            $state.go('home.second');
                        }, 0);
                }
            }
        })
        .state('home.first', {
            url: '',
            templateUrl: 'first.html',
            controller: 'FirstController'
        })
        .state('home.second', {
            url: '',
            templateUrl: 'second.html',
            controller: 'SecondController'
        });

Acabei tornando o controlador inicial um irmão do primeiro e do segundo, em vez de um pai, e então fiz o controlador inicial fazer um $state.go para o primeiro ou segundo, dependendo dos resultados da resolução.

Use código verificado para visualização condicional em ui-route

$stateProvider.state('dashboard.home', {
        url: '/dashboard',
        controller: 'MainCtrl',
       // templateUrl: $rootScope.active_admin_template,
        templateProvider: ['$stateParams', '$templateRequest','$rootScope', function ($stateParams, templateRequest,$rootScope) {
          var templateUrl ='';
          if ($rootScope.current_user.role == 'MANAGER'){
            templateUrl ='views/manager_portal/dashboard.html';
          }else{
            templateUrl ='views/dashboard/home.html';
          }
          return templateRequest(templateUrl);
        }]
      });
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top