Javascript AngularJS动态路由

Javascript AngularJS动态路由,javascript,angularjs,content-management-system,url-routing,Javascript,Angularjs,Content Management System,Url Routing,我目前有一个内置路由的AngularJS应用程序。 一切正常,一切正常 我的app.js文件如下所示: angular.module('myapp', ['myapp.filters', 'myapp.services', 'myapp.directives']). config(['$routeProvider', function ($routeProvider) { $routeProvider.when('/', { templateUrl: '/pages/home.h

我目前有一个内置路由的AngularJS应用程序。 一切正常,一切正常

我的app.js文件如下所示:

angular.module('myapp', ['myapp.filters', 'myapp.services', 'myapp.directives']).
  config(['$routeProvider', function ($routeProvider) {
      $routeProvider.when('/', { templateUrl: '/pages/home.html', controller: HomeController });
      $routeProvider.when('/about', { templateUrl: '/pages/about.html', controller: AboutController });
      $routeProvider.when('/privacy', { templateUrl: '/pages/privacy.html', controller: AboutController });
      $routeProvider.when('/terms', { templateUrl: '/pages/terms.html', controller: AboutController });
      $routeProvider.otherwise({ redirectTo: '/' });
  }]);
我的应用程序有一个内置的CMS,您可以在/pages目录中复制和添加新的html文件

我仍然希望通过路由提供程序,即使是新的动态添加的文件

在理想情况下,布线模式应为:

$routeProvider.when('/pagename,{templateUrl:'/pages/pagename.html',控制器:CMSController})

因此,如果我的新页面名为“contact.html”,我希望选择“/contact”并重定向到“/pages/contact.html”

这可能吗?!如果是这样,怎么办

更新

现在,我的路由配置中有以下内容:

$routeProvider.when('/page/:name', { templateUrl: '/pages/home.html', controller: CMSController })
$routeProvider.when('/pages/:name', {
    templateUrl: '/pages/home.html', 
    controller: CMSController 
});
在我的CMS控制器中:

function CMSController($scope, $route, $routeParams) {
    $route.current.templateUrl = '/pages/' + $routeParams.name + ".html";
    alert($route.current.templateUrl);
}
CMSController.$inject = ['$scope', '$route', '$routeParams'];
function CMSController($scope, $route, $routeParams) {

    $route.current.templateUrl = '/pages/' + $routeParams.name + ".html";

    $.get($route.current.templateUrl, function (data) {
        $scope.$apply(function () {
            $('#views').html($compile(data)($scope));
        });
    });
    ...
}
CMSController.$inject = ['$scope', '$route', '$routeParams'];
这将当前templateUrl设置为正确的值


但是,我现在想用新的templateUrl值更改ng视图。这是如何实现的?

在$routeProvider URI模式中,您可以指定可变参数,如:
$routeProvider.when(“/page/:pageNumber”…
),并通过$routeParams在控制器中访问它

$route页面末尾有一个很好的示例:

编辑(针对已编辑的问题):

不幸的是,路由系统非常有限-关于这个主题有很多讨论,并且已经提出了一些解决方案,即通过创建多个命名视图等。但是现在,ngView指令在一对一的基础上只为每条路由提供一个视图。您可以通过多种方式来实现这一点-更简单的方法是使用视图的模板作为加载程序,其中有一个
标记($scope.myTemplateUrl将在控制器中创建)

我使用更复杂(但更干净,用于更大和更复杂的问题)的解决方案,基本上完全跳过$route服务,详细内容如下:

好的,解决了

将解决方案添加到GitHub-

在my app.js路由配置中:

$routeProvider.when('/page/:name', { templateUrl: '/pages/home.html', controller: CMSController })
$routeProvider.when('/pages/:name', {
    templateUrl: '/pages/home.html', 
    controller: CMSController 
});
然后在我的CMS控制器中:

function CMSController($scope, $route, $routeParams) {
    $route.current.templateUrl = '/pages/' + $routeParams.name + ".html";
    alert($route.current.templateUrl);
}
CMSController.$inject = ['$scope', '$route', '$routeParams'];
function CMSController($scope, $route, $routeParams) {

    $route.current.templateUrl = '/pages/' + $routeParams.name + ".html";

    $.get($route.current.templateUrl, function (data) {
        $scope.$apply(function () {
            $('#views').html($compile(data)($scope));
        });
    });
    ...
}
CMSController.$inject = ['$scope', '$route', '$routeParams'];
将#视图作为我的

因此,现在它可以与标准路由和动态路由一起使用。

为了测试它,我复制了about.html,称之为portfolio.html,更改了它的一些内容,并将
/#/pages/portfolio
输入我的浏览器,然后显示了hey presto portfolio.html

已更新
将$apply和$compile添加到html中,以便注入动态内容。

我认为最简单的方法是稍后解析路由,例如,您可以通过json请求路由。请检查我是否在配置阶段通过$provide将$routeProvider制作成工厂,这样我就可以在t中继续使用$routeProvider对象他运行阶段,甚至在控制器中

'use strict';

angular.module('myapp', []).config(function($provide, $routeProvider) {
    $provide.factory('$routeProvider', function () {
        return $routeProvider;
    });
}).run(function($routeProvider, $http) {
    $routeProvider.when('/', {
        templateUrl: 'views/main.html',
        controller: 'MainCtrl'
    }).otherwise({
        redirectTo: '/'
    });

    $http.get('/dynamic-routes.json').success(function(data) {
        $routeProvider.when('/', {
            templateUrl: 'views/main.html',
            controller: 'MainCtrl'
        });
        // you might need to call $route.reload() if the route changed
        $route.reload();
    });
});

从AngularJS 1.1.3开始,您现在可以使用新的catch all参数完全执行您想要的操作

从提交:

这允许routeProvider接受匹配的参数 子字符串,即使它们包含斜杠(如果它们是前缀) 用星号代替冒号。 例如,
edit/color/:color/largecode/*largecode
将与这样的东西相匹配
http://appdomain.com/edit/color/brown/largecode/code/with/slashs


我自己已经测试过了(使用1.1.5),效果很好。请记住,每个新的URL都会重新加载控制器,因此要保持任何状态,您可能需要使用自定义服务。

不确定为什么会这样做,但在angular 1.2.0-rc.2中可以使用动态(或通配符,如果您喜欢)路由

http://code.angularjs.org/1.2.0-rc.2/angular.min.js
http://code.angularjs.org/1.2.0-rc.2/angular-route.min.js

angular.module('yadda', [
  'ngRoute'
]).

config(function ($routeProvider, $locationProvider) {
  $routeProvider.
    when('/:a', {
  template: '<div ng-include="templateUrl">Loading...</div>',
  controller: 'DynamicController'
}).


controller('DynamicController', function ($scope, $routeParams) {
console.log($routeParams);
$scope.templateUrl = 'partials/' + $routeParams.a;
}).
http://code.angularjs.org/1.2.0-rc.2/angular.min.js
http://code.angularjs.org/1.2.0-rc.2/angular-route.min.js
角度模块('yadda'[
“ngRoute”
]).
配置(函数($routeProvider,$locationProvider){
$routeProvider。
当(“/:a”{
模板:“正在加载…”,
控制器:“DynamicController”
}).
控制器('DynamicController',函数($scope,$routeParams){
控制台日志($routeParams);
$scope.templateUrl='partials/'+$routeParams.a;
}).
example.com/foo->加载“foo”部分

com/bar->加载“bar”部分

不需要在ng视图中进行任何调整。'/:a'大小写是我发现的唯一一个可以实现此目的的变量。'/:foo'不起作用,除非您的部分都是foo1、foo2等。'/:a'可以与任何部分名称一起使用

所有的值都会触发动态控制器-因此没有“否则”,但是,我认为这是您在动态或通配符路由场景中寻找的

angular.module('myapp', ['myapp.filters', 'myapp.services', 'myapp.directives']).
        config(['$routeProvider', function($routeProvider) {
        $routeProvider.when('/page/:name*', {
            templateUrl: function(urlattr){
                return '/pages/' + urlattr.name + '.html';
            },
            controller: 'CMSController'
        });
    }
]);
  • 添加*使您能够动态处理多个级别的目录。 示例:/page/cars/selling/list将被此提供商捕获
从文件(1.3.0)中:

“如果templateUrl是一个函数,则将使用以下命令调用它 参数:

{Array.}-从当前 $location.path()通过应用当前路由“

when(路径、路由):方法

  • 路径可以包含以冒号开头,以星号结尾的命名组:例如:name*。当路由匹配时,所有字符都急切地存储在给定名称下的$routeParams中

这里有另一个很好的解决方案

(function() {
    'use strict';

    angular.module('cms').config(route);
    route.$inject = ['$routeProvider'];

    function route($routeProvider) {

        $routeProvider
            .when('/:section', {
                templateUrl: buildPath
            })
            .when('/:section/:page', {
                templateUrl: buildPath
            })
            .when('/:section/:page/:task', {
                templateUrl: buildPath
            });



    }

    function buildPath(path) {

        var layout = 'layout';

        angular.forEach(path, function(value) {

            value = value.charAt(0).toUpperCase() + value.substring(1);
            layout += value;

        });

        layout += '.tpl';

        return 'client/app/layouts/' + layout;

    }

})();

这只适用于静态内容,如果我理解正确的话。这是因为在实例化控制器后,通过jQuery(angular的作用域之外)更改DOM。类似{{This}}的变量可能会起作用(我必须尝试)但指令很可能不会。请注意这一点,因为它现在可能有用,但以后可能会破坏代码。.没错,绑定不起作用,但对我来说,我不太担心,因为我只希望客户端能够添加新页面。我添加的任何页面都会通过路由配置进行适当指定。不过这是一个不错的解决方案