如何避免许多" $ routeProvider.when"在大型应用程序中

时间:2014-06-12 07:46:47

标签: javascript angularjs url-routing angularjs-routing

有没有办法编写一个方法来解析即将到来的$ location.path并加载一个特定的html模板或应用$ route。目前我有这么多的" Whens"对于我的应用程序,将在完成后加倍或加倍。

 .config(['$routeProvider',
 function ($routeProvider) {
  $routeProvider.
      //Home
      //User/Tenant/Register
   when('/register', { templateUrl: 'pages/Auth/register.html' }).
   when('/login', { templateUrl: 'pages/Auth/login.html' }).
      //User
   when('/user', { templateUrl: 'pages/User/list.html' }).
   when('/user/new', { templateUrl: 'pages/User/new.html' }).
   when('/user/:userId', { templateUrl: 'pages/User/detail.html' }).
   when('/user/edit/:userId', { templateUrl: 'pages/User/new.html' }).
         //Role
   when('/role', { templateUrl: 'pages/Role/list.html' }).
   when('/role/new', { templateUrl: 'pages/Role/new.html' }).
   when('/role/:roleId', { templateUrl: 'pages/Role/detail.html' }).
   when('/role/edit/:roleId', { templateUrl: 'pages/Role/new.html' }).
   when('/roleassign', { templateUrl: 'pages/Role/assign.html' }).
   when('/roledefine', { templateUrl: 'pages/Role/define.html' }).
        //Permissions
   when('/permission', { templateUrl: 'pages/Permission/list.html' }).
   when('/permission/new', { templateUrl: 'pages/Permission/new.html' }).
   when('/permission/:permissionId', { templateUrl: 'pages/Permission/detail.html' }).
   when('/permission/edit/:permissionId', { templateUrl: 'pages/Permission/new.html' }).
   when('/permissionassign', { templateUrl: 'pages/Permission/assign.html' }).
      //Counter
   when('/X', { templateUrl: 'pages/Counter/list.html' }).
   when('/X/new', { templateUrl: 'pages/Counter/new.html' }).
   when('/X/:counterId', { templateUrl: 'pages/Counter/detail.html' }).
   when('/X/edit/:counterId', { templateUrl: 'pages/Counter/new.html' }).
      //Company
   when('/Y', { templateUrl: 'pages/Y/list.html' }).
   when('/Y/new', { templateUrl: 'pages/Y/new.html' }).
   when('/Y/:companyId', { templateUrl: 'pages/Y/detail.html' }).
   when('/Y/edit/:companyId', { templateUrl: 'pages/Y/new.html' }).
      //Product
   when('/Z', { templateUrl: 'pages/Z/list.html' }).
   when('/Z/new', { templateUrl: 'pages/Z/new.html' }).
   when('/Z/:productId', { templateUrl: 'pages/Z/detail.html' }).
   when('/Z/edit/:productId', { templateUrl: 'pages/Z/new.html' }).
   otherwise({
       redirectTo: '/index',
       templateUrl: 'pages/dashboard.html'
   });
  //$locationProvider.html5Mode(true);
  }])

2 个答案:

答案 0 :(得分:4)

解决方案1:单独的配置脚本

您可以拥有多个配置,而不是单个配置。如果这有助于维护,我会将各个组分成自己的组,因此可以一次管理一个子集并使事物模式可管理。 您的应用程序似乎使用文件夹来分隔特定的功能组。使用这些配置脚本文件也可以完成相同的操作。它们可以包含在他们的脚本组中。

解决方案2:DRY代码

在您的代码中似乎有很多 whens 共享一些可以重构的常见约定,因此只有一个块可以为所有这些块运行而不会一遍又一遍地重复相同的代码。

angular.foreach([
        "user",
        "permission",
        "role",
        "X",
        "Y",
        ...
    ], function(value) {
    $routeProvider
        .when("/" + value, { templateUrl: "pages/" + value + "/list.html" })
        .when("/" + value + "/new", { ... })
        .when("/" + value + "/:" + value + "Id", { ... }),
        .when("/" + value + "/edit/:" + value + "Id", { ... })
});

但由于我通常在Javascript中实现简化的string.prototype.format函数来帮助进行字符串连接,所以我将这些行写成:

angular.foreach([
        "user",
        "permission",
        "role",
        "X",
        "Y",
        ...
    ], function(value) {
    $routeProvider
        .when("/{0}".format(value), { templateUrl: "pages/" + value + "/list.html" })
        .when("/{0}/new".format(value), { ... })
        .when("/{0}/:{0}Id".format(value), { ... }),
        .when("/{0}/edit/:{0}Id".format(value), { ... })
});

对于那些定义其他路由的组,我可以看到一个类似的模式,也可以重构(即 roles 也有 define assign )。在我之前的代码示例中,我只提供了一个字符串值数组。这些可以更改为提供一个对象,其属性设置为数组,并具有所需的其他操作并在迭代器函数中处理这些操作。

angular.forEach({
    user: [],
    role: ["assign", "define"],
    permission: ["assign"],
    ...
}, function(actions, key) {
    // same 4 as above by using "key" instead of "value"
    $routeProvider
        .when("/{0}".format(key), { ... })
        ...;
    // if element has additional actions, configure those as well
    angular.forEach(actions, function(action) {
        $routeProvider.when("/{0}{1}".format(key, action), { ... });
    });
});

简化string.prototype.format实施

String.prototype.format = String.prototype.format || function () {
    ///<summary>Replaces placeholders in string with provided parameters.</summary>

    "use strict";

    var args = arguments;

    return this.replace(/{(\d+)}/g, function (match, index) {
        return typeof (args[index]) != "undefined" ? args[+index] : "";
    });
};

答案 1 :(得分:0)

我没有使用ngRoute,而是uiRouter,我在上一个应用程序中实现了这个解决方案。它看起来像这样:(在CoffeeScript中,hovewer):

angular.module('myApp')
.config ($stateProvider) ->

    $stateProvider
    .state 'main.page',
    url: '/page/{staticName:[a-z0-9_]*}'
    templateUrl: (stateParams) ->
        '/views/page/' + stateParams.staticName + '.html'
    controller: 'PageCtrl'

也许在ngRouter中以同样的方式可能吗?...