Enrutamiento dinámico AngularJS


Actualmente tengo una aplicación AngularJS con enrutamiento integrado. Funciona y todo está bien.

Mi aplicación.el archivo js se ve así:

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

Mi aplicación tiene un CMS integrado donde puede copiar y agregar nuevos archivos html dentro del directorio /pages.

Me gustaría ir a través del proveedor de enrutamiento, aunque incluso para los nuevos archivos añadidos dinámicamente.

En un mundo ideal, el patrón de enrutamiento be:

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

Así que si mi nuevo nombre de página era " contacto.html "Me gustaría que angular recogiera" / contacto "y redirigiera a" /páginas/contacto.HTML".

¿Es esto posible?! y si es así ¿cómo?!

Update

Ahora tengo esto en mi configuración de enrutamiento:

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

Y en mi CMSController:

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

Esto establece el templateUrl actual a el valor correcto.

Sin embargo Ahora me gustaría cambiar el ng-view con el nuevo valor templateUrl. ¿Cómo se logra esto?

Author: Guillaume, 2012-12-03

7 answers

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'
        });
    }
]);
  • Agregar * le permite trabajar con múltiples niveles de directorios dinámicamente. Ejemplo: /página / coches / venta / lista será catch en este proveedor

De los documentos (1.3.0):

" Si templateUrl es una función, se llamará con lo siguiente parámetros:

{Array.}- parámetros de ruta extraídos de la corriente $ubicación.path () aplicando la ruta actual "

También

Cuando (ruta, ruta): Método

  • la ruta puede contener grupos nombrados que comienzan con dos puntos y terminan con una estrella: por ejemplo:nombre*. Todos los caracteres se almacenan ansiosamente en rout routeParams bajo el nombre dado cuando la ruta coincide.
 131
Author: Robin Rizvi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-06 20:40:01

Ok resuelto.

Agregó que la solución a GitHub - http://gregorypratt.github.com/AngularDynamicRouting

En mi aplicación.configuración de enrutamiento js:

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

Luego en mi controlador CMS:

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

Con # vistas siendo mi <div id="views" ng-view></div>

Así que ahora funciona con enrutamiento estándar y enrutamiento dinámico.

Para probarlo copié alrededor.html lo llamó cartera.html, cambió algunos de sus contenidos y entró /#/pages/portfolio en mi navegador y hey presto cartera.html fue mostrado....

Actualizado Agregado apply apply y compile compile al html para que el contenido dinámico pueda ser inyectado.

 37
Author: Greg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-31 13:53:37

Creo que la forma más fácil de hacer tal cosa es resolver las rutas más tarde, podría preguntar las rutas a través de json, por ejemplo. Comprobar que puedo hacer una fábrica de los $routeProvider durante la fase de configuración, a través de $proporcionan, para que yo pueda seguir utilizando el $routeProvider objeto en la fase de ejecución, e incluso en los controladores.

'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();
    });
});
 16
Author: eazel7,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-10 06:20:52

En los patrones URI $routeProvider, puede especificar parámetros variables, como: $routeProvider.when('/page/:pageNumber' ... , y acceder a ellos en su controlador a través de rout routeParams.

Hay un buen ejemplo al final de la página route route: http://docs.angularjs.org/api/ng. route ruta

EDITAR (para la pregunta editada):

El sistema de enrutamiento es desafortunadamente muy limitado - hay mucha discusión sobre este tema, y se han propuesto algunas soluciones, a saber, mediante la creación de múltiples nombres vistas, etc.. Pero en este momento, la directiva ngView solo sirve UNA vista por ruta, en una base de uno a uno. Puede hacer esto de varias maneras - la más simple sería usar la plantilla de la vista como un cargador, con una etiqueta <ng-include src="myTemplateUrl"></ng-include> en ella (scope scope.myTemplateUrl se crearía en el controlador).

Utilizo una solución más compleja (pero más limpia, para problemas más grandes y complicados), básicamente omitiendo el servicio route route por completo, que se detalla aquí:

Http://www.bennadel.com/blog/2420-Mapping-AngularJS-Routes-Onto-URL-Parameters-And-Client-Side-Events.htm

 7
Author: Tiago Roldão,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-03 10:58:24

No estoy seguro de por qué funciona esto, pero las rutas dinámicas (o comodín si lo prefiere) son posibles en 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;
}).

Example.com/foo - > carga" foo " parcial

Example.com/bar - > carga parcial" bar "

No hay necesidad de ningún ajuste en la vista ng. El caso'/: a ' es la única variable que he encontrado que logrará esto.. '/ : foo ' no funciona a menos que sus parciales sean todos foo1, foo2, etc... '/ : a ' funciona con cualquier nombre parcial.

Todos los valores activan la dinámica controlador - por lo que no hay "de otra manera", pero, creo que es lo que está buscando en un escenario de enrutamiento dinámico o comodín..

 5
Author: Matthew Luchak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-28 00:17:11

A partir de AngularJS 1.1.3, ahora puede hacer exactamente lo que desee utilizando el nuevo parámetro catch-all.

Https://github.com/angular/angular.js/commit/7eafbb98c64c0dc079d7d3ec589f1270b7f6fea5

Del commit:

Esto permite que routeProvider acepte parámetros que coincidan subcadenas incluso cuando contienen barras si están prefijadas con un asterisco en lugar de dos puntos. Por ejemplo, rutas como edit/color/:color/largecode/*largecode coincidirá con algo como esto http://appdomain.com/edit/color/brown/largecode/code/with/slashs.

Lo he probado yo mismo (usando 1.1.5) y funciona muy bien. Solo tenga en cuenta que cada nueva URL recargará su controlador, por lo que para mantener cualquier tipo de estado, es posible que deba usar un servicio personalizado.

 2
Author: Dave,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-27 01:03:06

Aquí hay otra solución que funciona bien.

(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;

    }

})();
 0
Author: kevinius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-14 11:24:05