AngularJS dynamic routing

I currently have an AngularJS application with routing built in. It works and everything is ok.

My app.js file looks like this:

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: '/' });
  }]);

My app has a CMS built in where you can copy and add new html files within the /pages directory.

I would like to still go through the routing provider though even for the new dynamically added files.

In an ideal world the routing pattern would be:

$routeProvider.when('/ pagename ', { templateUrl: '/pages/ pagename .html', controller: CMSController });

So if my new page name was "contact.html" I would like angular to pick up "/contact" and redirect to "/pages/contact.html".

Is this even possible?! and if so how?!

Update

I now have this in my routing config:

$routeProvider.when('/page/:name', { templateUrl: '/pages/home.html', controller: CMSController })

and in my CMSController:

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

This sets the current templateUrl to the right value.

However I would now like to change the ng-view with the new templateUrl value. How is this accomplished?


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'
        });
    }
]);
  • Adding * let you work with multiple levels of directories dynamically. Example: /page/cars/selling/list will be catch on this provider
  • From the docs (1.3.0):

    "If templateUrl is a function, it will be called with the following parameters:

    {Array.} - route parameters extracted from the current $location.path() by applying the current route"

    Also

    when(path, route) : Method

  • path can contain named groups starting with a colon and ending with a star: eg:name*. All characters are eagerly stored in $routeParams under the given name when the route matches.

  • Ok solved it.

    Added the solution to GitHub - http://gregorypratt.github.com/AngularDynamicRouting

    In my app.js routing config:

    $routeProvider.when('/pages/:name', {
        templateUrl: '/pages/home.html', 
        controller: CMSController 
    });
    

    Then in my CMS controller:

    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'];
    

    With #views being my <div id="views" ng-view></div>

    So now it works with standard routing and dynamic routing.

    To test it I copied about.html called it portfolio.html, changed some of it's contents and entered /#/pages/portfolio into my browser and hey presto portfolio.html was displayed....

    Updated Added $apply and $compile to the html so that dynamic content can be injected.


    I think the easiest way to do such thing is to resolve the routes later, you could ask the routes via json, for example. Check out that I make a factory out of the $routeProvider during config phase, via $provide, so I can keep using the $routeProvider object in the run phase, and even in controllers.

    '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();
        });
    });
    
    链接地址: http://www.djcxy.com/p/77616.html

    上一篇: 如何在AngularJS中处理锚点哈希链接

    下一篇: AngularJS动态路由