AngularJS - Как использовать $routeParams в генерации шаблонаUrl?

Наше приложение имеет двухуровневую навигацию. Мы хотим использовать AngularJS $routeProvider для динамического предоставления шаблонов <ng-view />. Я думал о том, чтобы что-то делать по этому поводу:

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

Я просто не знаю, как заполнить части в <<>>. Я знаю, что primaryNav и secondaryNav связаны с $routeParams, но как мне получить доступ к $routeParams здесь, чтобы динамически обслуживать шаблон?

Ответ 1

Я не мог найти способ ввода и использования службы $routeParams (которую я бы предположил, было бы лучшим решением). Я пробовал думать, что это может сработать:

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

Это дало эту ошибку:

Неизвестный поставщик: $routeParams из myApp

Если что-то подобное невозможно, вы можете изменить свой templateUrl на частичный HTML файл, который имеет только ng-include, а затем установить URL-адрес в вашем контроллере с помощью $routeParam следующим образом:

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

С этим в качестве urlRouter.html

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

Ответ 2

Эта очень полезная функция теперь доступна начиная с версии 1.1.2 AngularJS. Он считался нестабильным, но я использовал его (1.1.3), и он отлично работает.

В принципе вы можете использовать функцию для генерации строки templateUrl. Функция передает параметры маршрута, которые вы можете использовать для сборки и возврата строки templateUrl.

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

Большое спасибо https://github.com/lrlopez для запроса на перенос.

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

Ответ 3

templateUrl может использоваться как функция с возвращаемым сгенерированным URL-адресом. Мы можем манипулировать URL-адресом с передающим аргументом, который принимает routeParams.

См. пример.

.when('/:screenName/list',{
    templateUrl: function(params){
         return params.screenName +'/listUI'
    }
})

Надеюсь на эту помощь.

Ответ 4

Хорошо, думаю, я понял...

Маленький фон: Причина, по которой я нуждался в этом, заключалась в том, чтобы придерживаться Angular поверх Node Express и иметь Jade обрабатывать мои частичные для меня.

Итак, вот что нужно... (пить пиво и тратить на него еще 20 часов!!!)...

Когда вы настраиваете свой модуль, сохраните $routeProvider глобально:

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

});
...

Это может быть больше информации, чем нужно...

  • В принципе, вы захотите сохранить свой модуль $routeProvider var глобально, например, как routeProvider, чтобы его можно было получить с помощью ваших контроллеров.

  • Затем вы можете просто использовать routeProvider и создать новый маршрут (вы не можете "RESET маршрут" / "REpromise", вы должны создать новый), я просто добавил косую черту (/) в конце так, чтобы он был семантическим, как первый.

  • Затем (внутри вашего контроллера) установите templateUrl в представление, которое вы хотите нажать.

  • Извлеките свойство controller объекта .when(), чтобы вы не получили бесконечный цикл запроса.

  • И, наконец, (все еще внутри контроллера), используйте $location.path() для перенаправления к только что созданному маршруту.

Если вам интересно, как пощекотать приложение Angular в приложении Express, вы можете разблокировать мое репо здесь: https://github.com/cScarlson/isomorph.

И этот метод также позволяет вам сохранять двунаправленные привязки данных AngularJS на случай, если вы хотите привязать свой HTML к своей базе данных с помощью WebSockets: в противном случае без этого метода ваши привязки данных Angular будут просто выводить {{model.param}}.

Если вы клонируете это в это время, вам понадобится mongoDB на вашем компьютере, чтобы запустить его.

Надеюсь, что это решает эту проблему!

Коди

Не пейте свою ванну.

Ответ 5

Я добавил поддержку этого в свою вилку angular. Он позволяет указать

$routeProvider
    .when('/:some/:param/:filled/:url', {
          templateUrl:'/:some/:param/:filled/template.ng.html'
     });

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

Не уверен, что это будет воспринято, поскольку оно отчасти против зерна для angular, но оно мне полезно

Ответ 6

Router: -

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

Контроллер: -

...
// 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;
...

Я считаю, что это слабость в angularjs, что $routeParams НЕ отображается внутри маршрутизатора. Небольшое улучшение создало бы мир во время реализации.

Ответ 7

У меня была аналогичная проблема и я использовал $stateParams вместо routeParam