Разработка динамической маршрутизации
В настоящее время у меня есть приложение AngularJS со встроенной маршрутизацией. Это работает, и все в порядке.
Мои приложения.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, где вы можете копировать и добавлять новые html-файлы в / pages.
Я хотел бы по-прежнему пройти через поставщика маршрутизации, хотя даже для новых динамически добавляемых файлов.
В идеальном мире шаблон маршрутизации быть:
$routeProvider.когда('/pagename', { templateUrl: '/ pages/pagename.html', контроллер: CMSController });
Так что если мое новое имя страницы "Контакты.HTML-код" я хотел бы угловой, чтобы забрать "/контакт" и редирект на "/страницы/Контакты.формат HTML."
это вообще возможно?! и если да, то как?!
обновление
Теперь у меня есть это в моей конфигурации маршрутизации:
$routeProvider.when('/page/:name', { templateUrl: '/pages/home.html', controller: CMSController })
и в моем CMSController:
function CMSController($scope, $route, $routeParams) {
$route.current.templateUrl = '/pages/' + $routeParams.name + ".html";
alert($route.current.templateUrl);
}
CMSController.$inject = ['$scope', '$route', '$routeParams'];
это устанавливает текущее значение templateUrl в нужное значение.
теперь я хотел бы изменить ng-view С новым значением templateUrl. Как это достигается?
7 ответов:
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' }); } ]);
- добавление * позволяет работать с несколько уровней каталогов динамически. Пример: /страница/автомобили/продажа/список будет ловить на этом провайдере
документы (1.3.0):
" если templateUrl является функцией, она будет вызвана следующим образом параметры:
{массив.} - параметры маршрута, извлеченные из текущего $расположение.путь() по применение текущего маршрута"
и
когда(путь, путь) : метод
- путь может содержать именованные группы, начинающиеся с двоеточия и заканчивающиеся звездочкой: например:name*. Все символы охотно хранятся в $routeParams под заданным именем, когда маршрут совпадает.
ОК решили.
добавлено решение для GitHub - http://gregorypratt.github.com/AngularDynamicRouting
в моем приложении.конфигурация маршрутизации js:
$routeProvider.when('/pages/:name', { templateUrl: '/pages/home.html', controller: CMSController });
затем в моем контроллере 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'];
С #views быть моим
<div id="views" ng-view></div>
теперь он работает со стандартной маршрутизацией и динамической маршрутизацией.
чтобы проверить это я скопировала про.HTML, которая называется его портфелем.html, изменил некоторые из это содержимое и введено
/#/pages/portfolio
в мой браузер и привет presto портфолио.HTML-коде....Обновлено добавлены $apply и $compile в html, чтобы можно было вводить динамический контент.
Я думаю, что самый простой способ сделать это-решить маршруты позже, вы можете спросить маршруты через json, например. Проверьте, что я делаю фабрику из $routeProvider во время фазы конфигурации, через $provide, поэтому я могу продолжать использовать объект $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(); }); });
в $routeProvider скороговорки Ури, вы можете задать различные параметры, например, так:
$routeProvider.when('/page/:pageNumber' ...
, и получить доступ к нему в контроллере через $routeParams.есть хороший пример в конце страницы $ route: http://docs.angularjs.org/api/ng.$маршрут
EDIT (для отредактированного вопроса):
система маршрутизации, к сожалению, очень ограничен - есть много дискуссий на эту тему, и некоторые решения были предложены, а именно, путем создания нескольких именованных представлений и т. д.. Но прямо сейчас директива ngView обслуживает только один вид на маршрут, на индивидуальной основе. Вы можете сделать это несколькими способами - Проще было бы использовать шаблон представления в качестве загрузчика, с
<ng-include src="myTemplateUrl"></ng-include>
тег в нем ($scope.myTemplateUrl будет создан в контроллере).Я использую более сложное (но более чистое, для больших и более сложных проблем) решение, в основном пропуская службу $route вообще, то есть подробно здесь:
Не уверен, почему это работает, но динамические (или подстановочные, если вы предпочитаете) маршруты возможны в 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 - > загружает" foo " частично
example.com/bar - > загружает" бар " частично
нет необходимости в каких-либо корректировках в ng-view. Случай'/: a ' - единственная переменная, которую я нашел, которая достигнет этого.. '/: foo ' не работает, если ваши партиалы все foo1, foo2 и т. д... '/:работает с любой частичной имя.
все значения запускают динамический контроллер-поэтому нет "иначе", но я думаю, что это то, что вы ищете в динамическом или подстановочном сценарии маршрутизации..
начиная с AngularJS 1.1.3, теперь вы можете делать именно то, что хотите, используя новый параметр catch-all.
https://github.com/angular/angular.js/commit/7eafbb98c64c0dc079d7d3ec589f1270b7f6fea5
из фиксации:
Это позволяет routeProvider принимать параметры, которые соответствуют подстроки, даже если они содержат косые черты, если они имеют префикс со звездочкой вместо двоеточия. Например, маршруты типа
edit/color/:color/largecode/*largecode
будет матч с чем-то вроде этогоhttp://appdomain.com/edit/color/brown/largecode/code/with/slashs
.Я проверил его сам (используя 1.1.5), и он отлично работает. Просто имейте в виду, что каждый новый URL-адрес будет перезагружать ваш контроллер, поэтому для сохранения любого состояния вам может потребоваться использовать пользовательский сервис.
вот еще одно решение, которое работает хорошо.
(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; } })();