Saat ini saya memiliki aplikasi AngularJS dengan perutean bawaan. Ia bekerja dan semuanya baik-baik saja.
File app.js saya terlihat seperti ini:
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: '/' });
}]);
Aplikasi saya memiliki CMS bawaan tempat Anda dapat menyalin dan menambahkan file html baru di dalam direktori / pages .
Saya ingin tetap melalui penyedia perutean meskipun untuk file baru yang ditambahkan secara dinamis.
Dalam dunia yang ideal pola peruteannya adalah:
$ routeProvider.when ('/ pagename ', {templateUrl: '/ pages / pagename .html', controller: CMSController});
Jadi jika nama halaman baru saya adalah "contact.html", saya ingin angular untuk mengambil "/ contact" dan dialihkan ke "/pages/contact.html".
Apakah ini mungkin ?! dan jika demikian bagaimana ?!
Memperbarui
Saya sekarang memiliki ini di konfigurasi perutean saya:
$routeProvider.when('/page/:name', { templateUrl: '/pages/home.html', controller: CMSController })
dan di CMSController saya:
function CMSController($scope, $route, $routeParams) {
$route.current.templateUrl = '/pages/' + $routeParams.name + ".html";
alert($route.current.templateUrl);
}
CMSController.$inject = ['$scope', '$route', '$routeParams'];
Ini menyetel templateUrl saat ini ke nilai yang benar.
Namun sekarang saya ingin mengubah ng-view dengan nilai templateUrl baru. Bagaimana ini tercapai?
urlattr
ditetapkan atau dikirim, maksud saya apa yangurlattr.name
akan diproduksi?Ok menyelesaikannya.
Menambahkan solusi ke GitHub - http://gregorypratt.github.com/AngularDynamicRouting
Di konfigurasi perutean app.js saya:
$routeProvider.when('/pages/:name', { templateUrl: '/pages/home.html', controller: CMSController });
Kemudian di pengontrol CMS saya:
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'];
Dengan #views menjadi milikku
<div id="views" ng-view></div>
Jadi sekarang ini berfungsi dengan perutean standar dan perutean dinamis.
Untuk mengujinya, saya menyalin about.html menyebutnya portfolio.html, mengubah beberapa isinya dan masuk
/#/pages/portfolio
ke browser saya dan hei presto portfolio.html ditampilkan ....Diperbarui Menambahkan $ apply dan $ compile ke html sehingga konten dinamis dapat dimasukkan.
sumber
Menurut saya cara termudah untuk melakukannya adalah dengan menyelesaikan rute nanti, Anda bisa menanyakan rute melalui json, misalnya. Periksa bahwa saya membuat pabrik dari $ routeProvider selama fase konfigurasi, melalui $ menyediakan, jadi saya dapat tetap menggunakan objek $ routeProvider dalam fase run, dan bahkan di pengontrol.
'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(); }); });
sumber
$routeProvider
untuk digunakan sebagaifactory
(tersedia setelahconfig
) tidak akan berfungsi baik dengan keamanan dan kohesi aplikasi - bagaimanapun juga, teknik yang keren (suara positif!).Dalam pola URI $ routeProvider, Anda dapat menetapkan parameter variabel, seperti
$routeProvider.when('/page/:pageNumber' ...
:, dan mengaksesnya di pengontrol Anda melalui $ routeParams.Ada contoh yang bagus di akhir halaman $ route: http://docs.angularjs.org/api/ng.$route
EDIT (untuk pertanyaan yang diedit):
Sayangnya, sistem perutean sangat terbatas - ada banyak diskusi tentang topik ini, dan beberapa solusi telah diusulkan, yaitu melalui pembuatan beberapa tampilan bernama, dll. Tetapi saat ini, arahan ngView hanya melayani SATU tampilan per rute, di basis satu-ke-satu. Anda dapat melakukannya dengan berbagai cara - cara yang lebih sederhana adalah menggunakan template tampilan sebagai loader, dengan
<ng-include src="myTemplateUrl"></ng-include>
tag di dalamnya ($ scope.myTemplateUrl akan dibuat di controller).Saya menggunakan solusi yang lebih kompleks (tapi lebih bersih, untuk masalah yang lebih besar dan lebih rumit), pada dasarnya melewatkan layanan $ route sama sekali, yang dirinci di sini:
http://www.bennadel.com/blog/2420-Mapping-AngularJS-Routes-Onto-URL-Parameters-And-Client-Side-Events.htm
sumber
ng-include
metodenya. Ini sangat sederhana dan ini adalah pendekatan yang jauh lebih baik daripada memanipulasi DOM.Tidak yakin mengapa ini berfungsi tetapi rute dinamis (atau karakter pengganti jika Anda lebih suka) dimungkinkan dalam sudut 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 -> memuat sebagian "foo"
example.com/bar-> memuat sebagian "bar"
Tidak perlu penyesuaian apa pun dalam ng-view. Kasus '/:' adalah satu-satunya variabel yang saya temukan yang akan mencapai hal ini .. '/: foo' tidak berfungsi kecuali jika sebagian Anda adalah foo1, foo2, dll ... '/: a' berfungsi dengan sebagian nama.
Semua nilai mengaktifkan pengontrol dinamis - jadi tidak ada "sebaliknya" tetapi, menurut saya itulah yang Anda cari dalam skenario perutean dinamis atau karakter pengganti ..
sumber
Mulai AngularJS 1.1.3, Anda sekarang dapat melakukan apa yang Anda inginkan menggunakan parameter catch-all yang baru.
https://github.com/angular/angular.js/commit/7eafbb98c64c0dc079d7d3ec589f1270b7f6fea5
Dari komit:
Saya telah mengujinya sendiri (menggunakan 1.1.5) dan berhasil dengan baik. Perlu diingat bahwa setiap URL baru akan memuat ulang pengontrol Anda, jadi untuk mempertahankan status apa pun, Anda mungkin perlu menggunakan layanan khusus.
sumber
Berikut adalah solusi lain yang berfungsi dengan baik.
(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; } })();
sumber