【问题标题】:Routes loaded from an api - controller never called从 api 加载的路由 - 控制器从未调用
【发布时间】:2016-09-28 11:07:24
【问题描述】:

我正在尝试通过运行 ajax 调用并在我的 RouteProvidor 上设置路由来将路由加载到我的 angularJS 应用程序中。以下是我的代码。

var app = angular.module('app', ['ngRoute']);
var appRouteProvider;

app.config(['$routeProvider', '$locationProvider', 
                      function($routeProvider, $locationProvider) {
  $locationProvider.html5Mode({  
    enabled: true,
    requireBase: false
  });
  appRouteProvider = $routeProvider;

  appRouteProvider.when('/', {
    templateUrl : '../../app/templates/home.html',
    controller  : 'IndexController'
  });

}]).run(function($http, $route){

  url = siteApiRoot+'api/routes';

  $http.post(url, jQuery.param([]), {
      method: "POST",
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    }
  ).success(function(data){

    for(i in data){
        appRouteProvider.when(data[i].route, {
            templateUrl : data[i].template,
            controller  : data[i].controller
        });
    }

    console.log($route.routes);

  });
});

console.log 向控制台输出一组正确的路由,这似乎表明路由已正确分配。但是,如果我要打开任何应该由路由处理的 url。什么都没发生。基本资产加载,即导航栏和页脚,它们始终保持不变,但从不调用路线的控制器。我在这里想念什么。

-- 更新

从技术上讲,我的路线遵循以下模式:

条目列表:

/<city>/<category>
/<city>/<subdistrict>-<category>
/<city>/<entry-slug>

我不确定如何很好地定义上述内容 - 基本上前两条路线将调用一个控制器和一个视图,而第三条将调用另一个。但是,我坚持如何在 AngularJS 中定义这种路由,前提是 etc 都是数据库中的 slug。几乎只剩下硬编码一组路线,但这似乎也不起作用。

另外,我还有其他静态页面 - 例如 /about /site/contact - 在此处路由时有点丢失。

【问题讨论】:

  • 你的问题是Angular之前已经加载了所有的路由。您可能必须重新加载 routeService,但为什么您甚至必须通过 ajax 获取您的路线?对我来说,这听起来像是糟糕的设计。

标签: javascript angularjs


【解决方案1】:

初始化后无法更改路由器配置,但可以使用参数化路由来处理一切。

您可以在外部服务中获取路由数据,并使用您需要的任何查找逻辑为当前参数找到合适的条目。我认为这样做的目的是为这些路由提供不同的模板和控制器。

您可以使用简单的 ng-include 解决模板,但您必须手动实例化控制器。查看$injector 而不是此处的 $controller 调用以了解有关此问题的更多详细信息,因为您可能需要为它们进行完全依赖注入。这里的 RouteController 只是将自己的作用域传递给创建的控制器(此时它实际上就像任何通用服务一样),它已经被路由器附加到 container.html。请注意,ng-include 创建了一个子作用域,因此如果要在模板中的作用域上分配新变量,则必须小心。

(如果这是一个问题,您也可以手动获取、构建和附加模板:查看$templateRequest$templateCache 和 $compile 服务。(您必须创建一个指令将其附加到DOM))

这是准系统示例代码:

var app = angular.module('app', ['ngRoute']);

app.service("getRouteConfig", function($http) { 

  var routeRequest = $http.post(url, jQuery.param([]), {
      method: "POST",
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    }

  return function(params) {
    return routeRequest.then(function(routes) {
      // find route entry in backend data for current city, category/slug
      return routes[params.city][params.slug];
    });
  }
})

app.controller("RouteController", function(route, $scope, $controller) { 
  $controller(route.controller, {$scope: $scope});

})

app.config(function($routeProvider) {

  $routeProvider.when('/', {
    templateUrl : '../../app/templates/home.html',
    controller  : 'IndexController'
  });
  $routeProvider.when('/:city/:url', {
    templateUrl : '../../app/templates/container.html',
    controller  : 'RouteController',
    resolve: {
      route: function(getRouteConfig, $routeParams) {
        return getRouteConfig($routeParams);
    }
   }
  });

});

container.html:

<ng-include src='$resolve.route.template'>

【讨论】:

  • 我想我在这里得到了要点 - 从技术上讲,我有一组路线,就像你看过我拥有的那种路线一样。我只需要知道如何决定对哪个路由使用哪个控制器,因为路由非常相似并且只能通过一些基本逻辑来检测,即如果 /:param 是数组中的一个元素,则使用 X 控制器,否则使用 Y 控制器。我会把它的逻辑放在哪里?
  • 就在getRouteConfig 服务中的评论处,您可以从后端获取routes 集合,并从url 模式获取params。 (在这种情况下,/:city/:slug 模式将产生 params.cityparams.slug,您可以使用它们来选择要使用的路线)
  • 我明白了——顺便说一句,我被卡住的一件事——路由对象的值。应该在 routes[params.city][params.slug]; 中返回什么。我已经修改了我的代码,因此我不必进行 http 调用,而只需将参数的值与通过服务检索到的数组进行比较...
  • 我想我会解决不完全依赖 api 的路线 - 它的设计很糟糕,但我的路线确实需要依赖从 api 检索的数据。我会在这里提出另一个问题-感谢您的帮助:)
  • routes[params.city][params.slug] 只是用于查找匹配路由的逻辑示例,它返回与data 中类似的配置对象,具有controllertemplate 属性。但是,是的,如果你能找到一个更简单的方法,一定要这样做:)
【解决方案2】:

Angular 配置函数用于设置配置,用于初始化服务。这意味着尝试从 run() 函数更改配置将不会导致任何事情发生,因为该配置已被使用。

一种可能的选择是在发送到客户端的实际 js 文件中从服务器提供配置。否则没有简单的方法可以使用 $http 更改配置。

这里有更多讨论:use $http inside custom provider in app config, angular.js

【讨论】:

  • 请查看我的问题的更新,了解我要在此处解决的问题
猜你喜欢
  • 2013-05-14
  • 2019-09-09
  • 2017-02-10
  • 2016-08-06
  • 2014-02-03
  • 1970-01-01
  • 2012-01-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多