2013-03-10 21 views
12

在.NET MVC有@Url.Action()和回報率有url_for()如何創建一個「url_for」鏈接幫手AngularjJS

我無法找到angularjs類似的URL建築幫手。

我已經提供了構建url到$routeProvider所需的所有東西,例如:$routeProvider.urlFor("MyCtrl", {id: 5})可能很好。

我的主要目標是避免視圖和其他地方的硬編碼網址,並避免兩次重複url/routes模式。

UPDATE:

好像很難解釋什麼,我想的那麼這裏是我想什麼確切的例子:

而不是在viewes寫這個:

<a ng-href="/product/5">foo</a> 

我想寫這個:

<a ng-href="urlFor("ProductCtrl", {id:5})">foo</a> 

所以,如果以後我決定改變ProductCtrl的路徑我woul d不必更新此元素中的網址。

什麼是我的目標的好辦法?

回答

15

你可以與你的主模塊的運行裏面的東西像下面的(只是想出了它)嘗試()塊:

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; 
    }; 
}); 

這將擴展應用程序的根目錄範圍與新路徑()功能 - 因此它可以在應用程序的任何地方使用。它使用$ route服務來獲取控制器名稱和相應的路徑,所以你不必重複自己。

用法示例:

{{ path('LibraryController', { bookId : 'x', chapterId : 'y' }) }} 

活生生的例子在:http://plnkr.co/edit/54DfhPK2ZDr9keCZFPhk?p=preview

+1

這正是我所需要的。 – 2013-03-19 07:02:21

+1

當多個路線使用相同的控制器時,此解決方案就會陷入困境。我更新了它,以找到通過的參數滿足所需參數的第一條路線,然後我改變了我的路線順序以確保首先定義最具體的路線。也更新到Angular 1.2.21。感謝您的堅實起點@mirrormx!代碼在這裏:http://plnkr.co/edit/05ilcKRf3Zcm1XXYhz9i?p=preview – colllin 2014-08-11 19:29:52

+1

是的!現在我們如何將它推到角度的下一個版本? – bymannan 2014-09-14 19:43:00

2

有很多方法......一個自定義directiveng-click修改$location,或者使用ng-href一個函數來分析從對象的URL,它也以<a>標籤放置爲href

實施例使用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

+0

我的主要目標是避免硬編碼的URL在視圖和其他地方,並避免重複URL /路由模式兩次。你的例子重複已經寫入/配置在$ route – 2013-03-10 17:26:09

+0

的路由模式不清楚你的問題是什麼。提供一個更清晰地顯示問題的演示,或更好的解釋。 '$ routeprovider'將管理對url的更改,但很有可能視圖必須根據用戶交互進行實際更改。 – charlietfl 2013-03-10 17:56:19

+0

在.NET MVC中存在@ Url.Action(),而在RoR中存在url_for()。我想要角度相同的功能。這是輔助方法,它會使用您的路由配置爲您提供指向您的控制器的鏈接。 – 2013-03-10 18:00:48

0

看來,你想要的是剛剛被最近添加到angularui project的UI路由指令。有一套很好的開箱即用選項。

+0

UI路線看起來很有趣,但看看例子我不認爲這是我想要的。它看起來像我很難解釋我以後的功能,我會更新問題與更多的信息。 – 2013-03-15 08:56:29

1

在最近的一個項目,我想出了這個解決方案。它幫我解決右邊的時候我的需要。幫助你改進它以適合你的用例將會很有趣。

1.移動路線定義配置:

... 
ROUTES: { 
    PAGE1: '/page1/:id', 
    PAGE2: '/page2/:id/:name' 
}, 
... 

2.定義路線,使用從配置值:

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.設置服務來提供功能創建網址:

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); 
     } 
    }; 
}); 

== ==缺點

採用這種方法,我不得不定義的getter爲每個路由(有小於5,發展速度是至關重要的)