Angular ui-router完成条件视图

时间:2021-11-08 12:59:11

I am asking a similar question to this question: UI Router conditional ui views?, but my situation is a little more complex and I cannot seem to get the provided answer to work.

我问这个问题类似的问题:UI路由器条件ui视图?,但我的情况有点复杂,我似乎无法得到提供的工作答案。

Basically, I have a url that can be rendered two very different ways, depending on the type of entity that the url points to.

基本上,我有一个可以呈现两种截然不同的方式的URL,具体取决于url指向的实体类型。

Here is what I am currently trying

这是我目前正在尝试的

    $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'
        });

I set up a Resolve to fetch the actual entity from a restful service. Every thing seems to be working until I actually get to the transitionTo based on the type.

我设置了Resolve来从一个宁静的服务中获取实际的实体。似乎每件事情都有效,直到我真正根据类型进入transitionTo。

The transition seems to work, except the resolve re-fires and the getEntity fails because the id is null.

转换似乎有效,除了重新触发并且getEntity因为id为null而失败。

I've tried to send the id to the transitionTo calls, but then it still tries to do a second resolve, meaning the entity is fetched from the rest service twice.

我已经尝试将id发送到transitionTo调用,但是它仍然尝试进行第二次解析,这意味着实体从其余服务中获取两次。

What seems to be happening is that in the onEnter handler, the state hasn't actually changed yet, so when the transition happens, it thinks it is transitioning to a whole new state rather than to a child state. This is further evidenced because when I remove the entity. from the state name in the transitionTo, it believes the current state is root, rather than home. This also prevents me from using 'go' instead of transitionTo.

似乎正在发生的事情是,在onEnter处理程序中,状态实际上还没有改变,所以当转换发生时,它认为它正在转换到一个全新的状态而不是一个子状态。这进一步证明了,因为我删除了实体。从transitionTo中的州名来看,它认为当前的状态是root,而不是home。这也阻止我使用'go'而不是transitionTo。

Any ideas?

有任何想法吗?

4 个解决方案

#1


10  

The templateUrl can be a function as well so you check the type and return a different view and define the controller in the view rather than as part of the state configuration. You cannot inject parameters to templateUrl so you might have to use templateProvider.

templateUrl也可以是一个函数,因此您检查类型并返回不同的视图并在视图中定义控制器,而不是作为状态配置的一部分。您无法将参数注入templateUrl,因此您可能必须使用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>';
        }
    });
  }]
})

#2


9  

You can also do the following :

您还可以执行以下操作:

$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'
        });

#3


3  

I ended up making the home controller a sibling of first and second, rather than a parent, and then had the controller of home do a $state.go to first or second depending on the results of the resolve.

我最终让家庭控制器成为第一和第二的兄弟,而不是父母,然后让家庭的控制器根据解决的结果做第一或第二$ state.go。

#4


0  

Use verified code for conditional view in ui-route

在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);
        }]
      });

#1


10  

The templateUrl can be a function as well so you check the type and return a different view and define the controller in the view rather than as part of the state configuration. You cannot inject parameters to templateUrl so you might have to use templateProvider.

templateUrl也可以是一个函数,因此您检查类型并返回不同的视图并在视图中定义控制器,而不是作为状态配置的一部分。您无法将参数注入templateUrl,因此您可能必须使用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>';
        }
    });
  }]
})

#2


9  

You can also do the following :

您还可以执行以下操作:

$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'
        });

#3


3  

I ended up making the home controller a sibling of first and second, rather than a parent, and then had the controller of home do a $state.go to first or second depending on the results of the resolve.

我最终让家庭控制器成为第一和第二的兄弟,而不是父母,然后让家庭的控制器根据解决的结果做第一或第二$ state.go。

#4


0  

Use verified code for conditional view in ui-route

在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);
        }]
      });