Как создать ссылку на ссылку 'url_for' в AngularjJS
В .NET MVC есть @Url.Action()
, а в RoR есть url_for()
Я не мог найти подобный помощник сборки url в angularjs.
Я уже предоставляю все, что необходимо для создания url для $routeProvider
, поэтому что-то вроде: $routeProvider.urlFor("MyCtrl", {id: 5})
может быть приятным.
Моя главная цель здесь - избегать жестко заданных URL-адресов в просмотрах и других местах и избегать повторения шаблонов url/routes дважды.
UPDATE:
Кажется, что мне сложно объяснить, что я хочу, вот здесь - точный пример того, что я хочу:
Вместо того, чтобы писать это в виде:
<a ng-href="/product/5">foo</a>
Я хочу написать это:
<a ng-href="urlFor("ProductCtrl", {id:5})">foo</a>
Итак, если позже я решит изменить путь ProductCtrl, мне не нужно будет обновлять url в этом элементе.
Что было бы хорошим решением для моих целей?
Ответы
Ответ 1
Вы можете попробовать что-то вроде следующего (только что придумал) внутри вашего основного модуля run():
app.run(function($route, $rootScope)
{
$rootScope.path = function(controller, params)
{
// Iterate over all available routes
for(var path in $route.routes)
{
var pathController = $route.routes[path].controller;
if(pathController == controller) // Route found
{
var result = path;
// Construct the path with given parameters in it
for(var param in params)
{
result = result.replace(':' + param, params[param]);
}
return result;
}
}
// No such controller in route definitions
return undefined;
};
});
Это расширит область корня приложения с помощью новой функции path(), поэтому ее можно использовать в любом месте приложения. Он использует службу $route для получения имен контроллеров и соответствующих путей, поэтому вам не придется повторять себя.
Пример использования:
{{ path('LibraryController', { bookId : 'x', chapterId : 'y' }) }}
Живой пример: http://plnkr.co/edit/54DfhPK2ZDr9keCZFPhk?p=preview
Ответ 2
Существует множество подходов... пользовательский directive
или ng-click
для изменения $location
или с помощью функции в ng-href
для синтаксического анализа URL-адреса объекта и размещения его как href
в <a>
.
Пример использования ng-href
:
HTML:
<li ng-repeat="item in items">
<a ng-href="{{url(item)}}">{{item.txt}}</a>
</li>
JS:
function Ctrl($scope){
$scope.items=[
{id:1,txt:'foo'},
{id:2,txt:'bar'}
];
$scope.url=function(item){
return '#/'+item.id
}
}
Пример использования ng-click
и $location
HTML:
<a ng-click="newPath(item)">{{item.txt}}</a>
JS:
function Ctrl($scope){
$scope.items=[
{id:1,txt:'foo'},
{id:2,txt:'bar'}
];
$scope.newPath=function(item){
$location.path('/'+item.id)
}
}
DEMO: http://jsbin.com/ovemaq/3
Ответ 3
В одном из последних проектов я подошел к этому решению, и это помогло мне своевременно решить мои потребности. Будет интересно помочь вам улучшить его, чтобы он соответствовал вашим требованиям.
1. Переместить определение маршрутов в конфигурацию:
...
ROUTES: {
PAGE1: '/page1/:id',
PAGE2: '/page2/:id/:name'
},
...
2. Определите маршруты, используя значения из config:
app.config(['$routeProvider', 'config', function ($routeProvider, config) {
$routeProvider.when('/', {
templateUrl: 'partials/home.html',
controller: 'HomeCtrl'
});
$routeProvider.when(config.ROUTES.PAGE1, {
templateUrl: 'partials/page1.html',
controller: 'PageOneCtrl'
});
...
$routeProvider.otherwise({
redirectTo: '/'
});
}]);
3. Настройте службу, чтобы обеспечить функциональность для создания URL-адресов:
services.factory('routes', function (config) {
// populates `:param` placeholder in string with hash value
var parseString = function (string, parameters) {
if (!string) return '';
if (!parameters) return string;
for (var index in parameters) {
if (!parameters.hasOwnProperty(index)) continue;
string = string.replace(':' + index, parameters[index]);
}
return string;
};
return {
getPage1Link: function (urlParams) {
return '#' + parseString(config.ROUTES.PAGE1, urlParams);
}
};
});
== Недостатки ==
При таком подходе я должен был определить геттер для каждого маршрута (было меньше 5, а скорость разработки была жизненно важна)
Ответ 4
Похоже, что вам нужна директива ui-route, которая недавно была добавлена в проект angularui. Есть хороший набор готовых вариантов.