Сейчас у меня есть приложение AngularJS со встроенной маршрутизацией. Оно работает, и все в порядке.
Мой файл app.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.when ('/ pagename ', {templateUrl: '/ pages / pagename .html', controller: CMSController});
Так что, если бы мое новое имя страницы было «contact.html», я бы хотел, чтобы angular взял «/ contact» и перенаправил на «/pages/contact.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. Как это достигается?
urlattr
ставится или отправляется, то есть чтоurlattr.name
будет производить?Хорошо решил это.
Добавлено решение в GitHub - http://gregorypratt.github.com/AngularDynamicRouting
В моей конфигурации маршрутизации app.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>
Итак, теперь он работает со стандартной маршрутизацией и динамической маршрутизацией.
Чтобы проверить это, я скопировал файл about.html, назвал его портфолио.html, изменил его содержимое и ввел
/#/pages/portfolio
в свой браузер, и на экране появилось сообщение hey prestofolio.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
Использование псевдонима в качествеfactory
(доступного послеconfig
) не будет хорошо работать с безопасностью и связностью приложений - в любом случае, крутая техника (голос за!).В шаблонах URI $ routeProvider вы можете указать переменные параметры, например:,
$routeProvider.when('/page/:pageNumber' ...
и получить к нему доступ в своем контроллере через $ routeParams.В конце страницы $ route есть хороший пример: http://docs.angularjs.org/api/ng.$route
РЕДАКТИРОВАТЬ (для отредактированного вопроса):
Система маршрутизации, к сожалению, очень ограничена - по этой теме ведется много дискуссий, и были предложены некоторые решения, а именно создание нескольких именованных представлений и т. Д. Но прямо сейчас директива ngView обслуживает только ОДНО представление для каждого маршрута на взаимно однозначная основа. Вы можете сделать это несколькими способами - проще было бы использовать шаблон представления в качестве загрузчика с
<ng-include src="myTemplateUrl"></ng-include>
тегом в нем ($ scope.myTemplateUrl будет создан в контроллере).Я использую более сложное (но более чистое, для более крупных и сложных проблем) решение, в основном полностью пропуская службу $ route, которая подробно описана здесь:
http://www.bennadel.com/blog/2420-Mapping-AngularJS-Routes-Onto-URL-Parameters-And-Client-Side-Events.htm
источник
ng-include
метод. Это действительно просто, и это намного лучший подход, чем манипулирование DOM.Не уверен, почему это работает, но динамические (или подстановочные знаки, если хотите) маршруты возможны в 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 и т.д ... '/: a' работает с любыми частичными название.
Все значения запускают динамический контроллер - так что нет никакого «другого», но я думаю, что это то, что вы ищете в сценарии динамической или групповой маршрутизации.
источник
Начиная с AngularJS 1.1.3, вы можете делать именно то, что хотите, используя новый универсальный параметр.
https://github.com/angular/angular.js/commit/7eafbb98c64c0dc079d7d3ec589f1270b7f6fea5
Из коммита:
Я тестировал это сам (используя 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; } })();
источник