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

Nom*_*aki 3 javascript custom-routes angularjs angular-ui-router

我正在尝试根据该问题的答案将状态动态添加到我的应用程序: 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");    
    });
}]);
Run Code Online (Sandbox Code Playgroud)

然而,我被困在接受答案的最后一个评论中的那个人,状态被创建,但我需要将用户重定向到正确的状态,而不是简单地将它们重定向到家,我无法得到$state.current.

现在我正在解析所有可用的状态,并尝试找到与当前网址的匹配,如果找到匹配,我将它们重定向到它.我看到一个我不记得的人,就这样做.

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

  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});
  }
Run Code Online (Sandbox Code Playgroud)

您是否知道更好的方法来实现这一目标,即使是抽象状态也可以使用?

非常感谢你的回答 !

Rad*_*ler 5

答案也在本问答中显示 - 我们的助手将有两种方法:

  • 提供者 - $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 Code Online (Sandbox Code Playgroud)

这是.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();
  }
]);
Run Code Online (Sandbox Code Playgroud)

检查这个workig plunker

此解决方案的文档在此处

$ urlRouterProvider

deferIntercept(defer)

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

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

引用片段:

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();
});
Run Code Online (Sandbox Code Playgroud)