現在、ルーティングが組み込まれた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: '/' });
}]);
私のアプリには、/ pagesディレクトリ内に新しいhtmlファイルをコピーして追加できるCMSが組み込まれています。
動的に追加された新しいファイルであっても、ルーティングプロバイダーを引き続き調べたいと思います。
理想的な世界では、ルーティングパターンは次のようになります。
$ 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値。これはどのように達成されますか?
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が関数の場合、次のパラメーターで呼び出されます。
{Array。}-現在のルートを適用することにより、現在の$ location.path()から抽出されたルートパラメーター」
また
when(path、route):メソッド
- pathには、コロンで始まりスターで終わる名前付きグループを含めることができます(例:name *)。ルートが一致すると、すべてのキャラクターは指定された名前で$ routeParamsに熱心に保存されます。
わかった。
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>
である
したがって、標準ルーティングと動的ルーティングで動作するようになりました
それをテストするために、portfolio.htmlというabout.htmlをコピーし、その内容の一部を変更して、ブラウザに/#/pages/portfolio
を入力すると、presto Portfolio.htmlが表示されました。
Updatedhtmlに$ applyと$ compileを追加して、動的にコンテンツを注入できます。
そのようなことをする最も簡単な方法は、後でルートを解決することだと思います。たとえば、json経由でルートを尋ねることができます。構成フェーズ中に$ provideを使用して$ routeProviderからファクトリーを作成することを確認してください。これにより、実行フェーズやコントローラーで$ 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 URIパターンでは、次のように変数パラメーターを指定できます:$routeProvider.when('/page/:pageNumber' ...
、コントローラーで$ routeParamsを介してアクセスします。
$ routeページの最後に良い例があります: http://docs.angularjs.org/api/ng.$route
EDIT(編集された質問用):
ルーティングシステムは残念ながら非常に限られています。このトピックについては多くの議論があり、複数の名前付きビューの作成など、いくつかのソリューションが提案されています。しかし、現在、ngViewディレクティブは1対1ベース。これについては複数の方法で実行できます。より簡単な方法は、ビューのテンプレートをローダーとして使用し、その中に<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ビューで調整する必要はありません。 '/: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;
}
})();