96 votes

AngularJS - Comment utiliser $routeParams dans la génération de la templateUrl?

Notre application a 2-au niveau de la navigation. Nous voulons utiliser AngularJS $routeProvider dynamiquement fournir des modèles pour un <ng-view />. Je pensais faire quelque chose le long des lignes de cette:

angular.module('myApp', []).
config(['$routeProvider', function($routeProvider) {
    $routeProvider.when('/:primaryNav/:secondaryNav', {
        templateUrl: 'resources/angular/templates/nav/'+<<primaryNavHere>>+'/'+<<secondaryNavHere>>+'.html'
    });
}]);

Je ne sais pas comment remplir les parties dans l' <<>>. Je sais que le primaryNav et secondaryNav se limite à l' $routeParams, mais comment puis-je accéder à $routeParams ici afin de diffuser de manière dynamique le modèle?

131voto

jlareau Points 1054

Cette caractéristique est très utile maintenant disponibles à partir de la version 1.1.2 de AngularJS. Il est considéré comme instable, mais je l'ai utilisé (1.1.3) et il fonctionne très bien.

Fondamentalement, vous pouvez utiliser une fonction pour générer un templateUrl chaîne. La fonction est passée les paramètres de l'itinéraire que vous pouvez utiliser pour construire et retour le templateUrl chaîne.

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

app.config(
    function($routeProvider) {
        $routeProvider.
            when('/', {templateUrl:'/home'}).
            when('/users/:user_id', 
                {   
                    controller:UserView, 
                    templateUrl: function(params){ return '/users/view/' + params.user_id; }
                }
            ).
            otherwise({redirectTo:'/'});
    }
);

Un grand merci à https://github.com/lrlopez pour le pull request.

https://github.com/angular/angular.js/pull/1524

84voto

Gloopy Points 16421

Je ne pouvais pas trouver un moyen d'insérer et d'utiliser le $routeParams service (qui, je suppose que ce serait une meilleure solution), j'ai essayé cette pensée, il peut fonctionner:

angular.module('myApp', []).
    config(function ($routeProvider, $routeParams) {
        $routeProvider.when('/:primaryNav/:secondaryNav', {
            templateUrl: 'resources/angular/templates/nav/'+$routeParams.primaryNav+'/'+$routeParams.secondaryNav+'.html'
        });
    });

Ce qui a abouti à cette erreur: Inconnu fournisseur de: $routeParams de myApp

Si quelque chose comme ça n'est pas possible, vous pouvez changer votre templateUrl à point partiel d'un fichier html qui a juste ng-inclure et puis définissez l'url dans votre contrôleur à l'aide de $routeParams comme ceci:

angular.module('myApp', []).
    config(function ($routeProvider) {
        $routeProvider.when('/:primaryNav/:secondaryNav', {
            templateUrl: 'resources/angular/templates/nav/urlRouter.html',
            controller: 'RouteController'
        });
    });

function RouteController($scope, $routeParams) {
        $scope.templateUrl = 'resources/angular/templates/nav/'+$routeParams.primaryNav+'/'+$routeParams.secondaryNav+'.html';
    }

Avec ce que votre urlRouter.html

<div ng-include src="templateUrl"></div>

7voto

Cody Points 1198

Bien, je pense que je l'ai eu...

Peu d'histoire d'abord: La raison que j'avais besoin c'était de coller Angulaire sur le dessus du Nœud Express et ont Jade traiter mes partiels pour moi.

Voici donc whatchya dois faire... (boire de la bière et passer plus de 20 heures sur le premier!!!)...

Lorsque vous configurez votre module, économiser de l' $routeProvider dans le monde:

// app.js:
var routeProvider
    , app = angular.module('Isomorph', ['ngResource']).config(function($routeProvider){

        routeProvider = $routeProvider;
        $routeProvider
            .when('/', {templateUrl: '/login', controller: 'AppCtrl'})
            .when('/home', {templateUrl: '/', controller: 'AppCtrl'})
            .when('/login', {templateUrl: '/login', controller: 'AppCtrl'})
            .when('/SAMPLE', {templateUrl: '/SAMPLE', controller: 'SAMPLECtrl'})
            .when('/map', {templateUrl: '/map', controller: 'MapCtrl'})
            .when('/chat', {templateUrl: '/chat', controller: 'ChatCtrl'})
            .when('/blog', {templateUrl: '/blog', controller: 'BlogCtrl'})
            .when('/files', {templateUrl: '/files', controller: 'FilesCtrl'})
            .when('/tasks', {templateUrl: '/tasks', controller: 'TasksCtrl'})
            .when('/tasks/new', {templateUrl: '/tasks/new', controller: 'NewTaskCtrl'})
            .when('/tasks/:id', {templateUrl: '/tasks', controller: 'ViewTaskCtrl'})
            .when('/tasks/:id/edit', {templateUrl: '/tasks', controller: 'EditTaskCtrl'})
            .when('/tasks/:id/delete', {templateUrl: '/tasks', controller: 'DeleteTaskCtrl'})
        .otherwise({redirectTo: '/login'});

});

// ctrls.js
...
app.controller('EditTaskCtrl', function($scope, $routeParams, $location, $http){

    var idParam = $routeParams.id;
    routeProvider.when('/tasks/:id/edit/', {templateUrl: '/tasks/' + idParam + '/edit'});
    $location.path('/tasks/' + idParam + '/edit/');

});
...

Que peut être plus d'infos que ce qui était nécessaire...

  • Fondamentalement, u voudra stocker votre Module $routeProvider var à l'échelle mondiale, par exemple, que routeProvider , de sorte qu'il peut être consulté par vos Contrôleurs.

  • Ensuite, vous pouvez simplement utiliser routeProvider et de créer une NOUVELLE route (vous ne pouvez pas RÉINITIALISER un itinéraire' / 'REpromise'; vous devez en créer un nouveau), j'ai juste ajouté une barre oblique (/) à la fin de sorte qu'il est aussi sémantique que le premier.

  • Ensuite (à l'intérieur de votre Contrôleur), définir l' templateUrl à la vue que vous voulez frapper.

  • Prendre l' controller de la propriété de l' .when() objet, de peur que vous obtenez une infinie demande de boucle.

  • Et enfin (toujours à l'intérieur de l'automate), utilisez $location.path() pour rediriger vers la route qui vient d'être créé.

Si vous êtes intéressé par la façon de claque Angulaire application sur un Express app, vous pouvez fourche mon repo ici: https://github.com/cScarlson/isomorph.

Et cette méthode permet également pour vous de garder le AngularJS Bidirectionnelle de Données des Fixations dans le cas où vous voulez lier votre code HTML à votre base de données utiliser les WebSockets: sinon, sans cette méthode, votre Angulaire de données-les liaisons juste sortie {{model.param}}.

Si vous avez un clone à ce moment, vous aurez besoin de mongoDB sur votre machine pour l'exécuter.

Espérons que cela résout ce problème!

Cody

Ne pas boire votre eau du bain.

3voto

Jamie Pate Points 470

J'ai ajouté le support pour ce dans ma fourchette de anguleux. Il vous permet de spécifier $routeProvider.when('/:some/:param/:filled/:url',{templateUrl:'/:some/:param/:filled/template.ng.html'});

https://github.com/jamie-pate/angular.js/commit/dc9be174af2f6e8d55b798209dfb9235f390b934

pas sûr que cela aura ramassé comme il est une sorte de contre le grain angulaire, mais il est utile pour moi

3voto

Ron deBoer Points 41

Routeur:-

...
.when('/enquiry/:page', {
    template: '<div ng-include src="templateUrl" onload="onLoad()"></div>',
    controller: 'enquiryCtrl'
})
...

Contrôleur:-

...
// template onload event
$scope.onLoad = function() {
    console.log('onLoad()');
    f_tcalInit();  // or other onload stuff
}

// initialize
$scope.templateUrl = 'ci_index.php/adminctrl/enquiry/'+$routeParams.page;
...

Je crois que c'est une faiblesse dans angularjs que $routeParams n'est PAS visible à l'intérieur du routeur. Une petite amélioration serait de faire un monde de différence au cours de la mise en œuvre.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X