AngularJS - ui.router - 如何在动态添加它们后重定向到所需的状态

AngularJS - ui.router - How to redirect to the needed state after adding them dynamicaly?

本文关键字:重定向 状态 添加 router ui AngularJS 动态      更新时间:2023-09-26

我正在尝试按照该问题的答案将状态动态添加到我的应用程序中:AngularJS - UI-router - 如何配置动态视图

app.run(['$q', '$rootScope', '$state', '$http',
  function ($q, $rootScope, $state, $http) 
  {
    $http.get("myJson.json")
    .success(function(data)
    {
      angular.forEach(data, function (value, key) 
      { 
          var state = {
            "url": value.url,
            "parent" : value.parent,
            "abstract": value.abstract,
            "views": {}
          };
          // here we configure the views
          angular.forEach(value.views, function (view) 
          {
            state.views[view.name] = {
              templateUrl : view.templateUrl,
            };
          });
          $stateProviderRef.state(value.name, state);
      });
      $state.go("home");    
    });
}]);
但是,我

像那个人在接受答案的最后一条评论中一样被困住了,状态已创建,但我需要将用户重定向到正确的状态,而不仅仅是简单地将他们重定向到主页,我无法获得$state.current.

现在,我正在解析所有可用的状态并尝试找到与当前 url 的匹配项,如果找到匹配项,我会将它们重定向到它。我看到一个我不记得在哪里的人,像这样做。

除了抽象状态外,它工作正常。这是代码:

  var matchedState = null,
    matchedStateParams = null;
  angular.forEach($state.get(), function(state) {
    var url = state.url ? $urlMatcherFactory.compile(state.url) : null;
    var params = url ? url.exec($location.path(), $location.search()) : null;
    if (!matchedState && params && !state.abstract) {
      matchedState = state;
      matchedStateParams = params;
    }
  });
  if(matchedState != null) {
    $state.transitionTo(matchedState, matchedStateParams, {reload: true});
  }

您是否知道实现此目的的更好方法,即使抽象状态也有效?

非常感谢您的回答!

答案也在这个问答中显示出来——我们的帮手将有两种方法:

  • 提供商 - $urlRouterProvider.deferIntercept();
  • 服务 - $urlRouter.listen();

如文档中所述(请参阅下面的引用部分),一旦动态定义了所有状态,我们就可以使用 UI-Router 的强大功能在配置阶段"停止 url 评估",并在运行阶段"再次重新运行它"......

这将是.config()阶段的一部分

.config(['$stateProvider', '$urlRouterProvider',
  function($stateProvider, $urlRouterProvider) {
      $stateProviderRef = $stateProvider; 
       
      // here we will define default
      // and instract UI-Router to wait and wait and wait
      $urlRouterProvider.otherwise('/home');
      $urlRouterProvider.deferIntercept();

这是.run()阶段

.run(['$rootScope', '$urlRouter',
  function($rootScope, $urlRouter) {    
    $stateProviderRef
      .state('home', {
        url: "/home",
        templateUrl: 'tpl.html',
      })
    // now we will stop the waiting
    // the url evaluation will start again, and even dynamic stuff
    // will be properly triggered
    $urlRouter.listen();
  }
]);

检查此工作

此解决方案的文档位于此处

$urlRouterProvider

deferIntercept(defer)

禁用(或启用)延迟位置更改拦截。

如果要自定义同步 URL 的行为(例如,如果希望延迟转换但保留当前 URL),请在配置时调用此方法。然后,在运行时,在配置自己的$locationChangeSuccess事件处理程序后调用$urlRouter.listen()

引用片段:

var app = angular.module('app', ['ui.router.router']);
app.config(function($urlRouterProvider) {
  // Prevent $urlRouter from automatically intercepting URL changes;
  // this allows you to configure custom behavior in between
  // location changes and route synchronization:
  $urlRouterProvider.deferIntercept();
}).run(function($rootScope, $urlRouter, UserService) {
  $rootScope.$on('$locationChangeSuccess', function(e) {
    // UserService is an example service for managing user state
    if (UserService.isLoggedIn()) return;
    // Prevent $urlRouter's default handler from firing
    e.preventDefault();
    UserService.handleLogin().then(function() {
      // Once the user has logged in, sync the current URL
      // to the router:
      $urlRouter.sync();
    });
  });
  // Configures $urlRouter's listener *after* your custom listener
  $urlRouter.listen();
});