javascript - 来自服务器数据的动态路由

标签 javascript angularjs angular-ui-router state

我有一些动态定义的嵌套路由:

var res = [
  {i:1,title:"title 1"},
  {i:2,title:"title 2"},
  {i:3,title:"title 3"},
  {i:4,title:"title 4"}
];

app.config(function($stateProvider, $urlRouterProvider, $authProvider,$httpProvider) {
    // other routes [...]
    angular.forEach(res, function(d) {
        $stateProvider.state('nested.q' + d.i, {
           url: '/' + d.i,
           template: '{{d.i}} - {{d.title}}'
       });
    });  
});

var res 应该在 ajax 中从服务器检索,我不确定如何在 Angular 工作流的这个步骤中完成它(在任何服务或 Controller 加载之前)。

根据@Radim Köhler 的回答进行编辑 我试过这段代码,这有什么问题?路线根本没有注册:

var  $stateProviderRef; // is this global var used like you thought??
app.config(function($stateProvider, $urlRouterProvider,$httpProvider,$locationProvider) {

$stateProvider
    .state('about', {
        url: "/about",
        templateUrl: "/partials/about.html"
    })
$urlRouterProvider.deferIntercept();
$locationProvider.html5Mode({enabled: false});
$stateProviderRef = $stateProvider;

$urlRouterProvider.otherwise('/');

});

app.run([ '$rootScope','$http', '$urlRouter',
    function ($rootScope, $http, $urlRouter)
    {
        $http
            .get("/api/remoteStates")
            .success(function(data)
            {
                angular.forEach(data, function (value, key)
                {
                    console.log(value)
                    $stateProviderRef.state(value.name, {
                        url: value.url,
                        template: value.template
                    });
                });
                $urlRouter.sync();
                $urlRouter.listen();
            });
    }]);

/api/remoteState 响应:

[
  {
    "name": "state1",
    "url": "state1",
    "template": "<h1>state1</h1>"
  },
  {
    "name": "state2",
    "url": "state2",
    "template": "<h1>state2</h1>"
  }
]

最佳答案

扩展:

基于扩展问题,有a working example . JSON 调整如下:

// api/remoteStates.json
[
  {
    "name": "state1",
    "url": "/state1",
    "template": "<h1>state1</h1>"
  },
  {
    "name": "state2",
    "url": "/state2",
    "template": "<h1>state2</h1>"
  }
]

而且这是几乎不变的状态注册

// script.js - first part CONFIG phase
app.config(function ($locationProvider, $urlRouterProvider, $stateProvider) {

    $stateProvider
     .state('about', {
        url: "/about",
        templateUrl: "partials/about.html"
    })

    $urlRouterProvider.deferIntercept();
    $urlRouterProvider.otherwise('/about');

    $locationProvider.html5Mode({enabled: false});
    $stateProviderRef = $stateProvider;
});

app.run(['$rootScope', '$state', '$stateParams',
  function ($rootScope, $state, $stateParams) {
    $rootScope.$state = $state;
    $rootScope.$stateParams = $stateParams;
}])

和运行部分

// script.js - RUN phase
app.run([ '$rootScope','$http', '$urlRouter',
    function ($rootScope, $http, $urlRouter)
    {
        $http
            .get("api/remoteStates.json")
            .success(function(data)
            {
                angular.forEach(data, function (value, key)
                {
                    console.log(value)
                    $stateProviderRef.state(value.name, {
                        url: value.url,
                        template: value.template
                    });
                });
                $urlRouter.sync();
                $urlRouter.listen();
            });
    }]);

检查所有 here in action

原创部分 检查此问答:

AngularJS - UI-router - How to configure dynamic views

如此处记录

$urlRouterProvider

The deferIntercept(defer)

Disables (or enables) deferring location change interception.

If you wish to customize the behavior of syncing the URL (for example, if you wish to defer a transition but maintain the current URL), call this method at configuration time. Then, at run time, call $urlRouter.listen() after you have configured your own $locationChangeSuccess event handler.

有一个working plunker

我们需要在配置阶段(推迟执行)

app.config(function ($locationProvider, $urlRouterProvider, $stateProvider) {

    // Prevent $urlRouter from automatically intercepting URL changes;
    // this allows you to configure custom behavior in between
    // location changes and route synchronization:
    $urlRouterProvider.deferIntercept();
    $urlRouterProvider.otherwise('/other');

    $locationProvider.html5Mode({enabled: false});
    $stateProviderRef = $stateProvider;
});

然后,我们在 run 阶段从服务器 ($http) 获取数据,一旦创建了新的动态状态...只需调用 同步

app.run([ '$rootScope','$http', '$urlRouter',
  function ($rootScope, $http, $urlRouter) 
  {
    $http
      .get("myJson.json")
      .success(function(data)
      {
        angular.forEach(data, function (value, key) 
        { 
          var state = {
            "url": ...
            "parent" :  ...
            "abstract":  ...
            "views": { ... }
          };

          angular.forEach(value.views, function (view) 
          {
            state.views[view.name] = {
              templateUrl : view.templateUrl,
            };
          });

          $stateProviderRef.state(value.name, state);
        });
        // Configures $urlRouter's listener *after* your custom listener            
        $urlRouter.sync();
        $urlRouter.listen();
      });
}]);

关于javascript - 来自服务器数据的动态路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39195813/

相关文章:

javascript - 更改运行php代码的链接的值

javascript - 除了选择元素之外,如何使用 Angular ng-options?

javascript - AngularJS $timeout 在计算值之前不等待 UI-Router 完成渲染

angularjs - 如何在动态html模板中添加ui-sref?

javascript - 无法阻止基于ajax检查的提交

javascript - javascript 中的 promise 会干扰其余代码

java - 跳过 Spring 中的 CORS 并配置项目以使用 Aptana

AngularJs:为什么当我使用 ng-click 时 ng-switch 不更新?

javascript - Angular 路由结果为 404 - 无法获取

javascript - 优化 JavaScript for 循环真的有必要吗?