如何在AngularjS中创建一个'url for'链接帮助器

时间:2013-03-10 15:41:30

标签: url routing angularjs angularjs-routing

在.NET MVC中有@Url.Action(),在RoR中有url_for()

我在angularjs中找不到类似的url构建帮助器。

我已经提供了构建网址$routeProvider所需的所有内容,所以像$routeProvider.urlFor("MyCtrl", {id: 5})这样的内容可能很棒。

我的主要目标是避免在视图和其他地方使用硬编码的网址,并避免重复网址/路由模式两次。

更新:

似乎很难解释我想要的东西所以这里是我想要的确切例子:

而不是在视图中写这个:

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

我想写这个:

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

因此,如果以后我决定改变ProductCtrl的路径,我就不必在这个元素中更新url。

对我的目标有什么好处?

4 个答案:

答案 0 :(得分:15)

您可以在主模块的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

答案 1 :(得分:2)

有许多方法......自定义directiveng-click来修改$location,或使用ng-href中的函数来解析来自对象的网址并拥有它已放置在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

答案 2 :(得分:1)

在最近的一个项目中,我找到了这个解决方案,它帮助我及时解决了我的需求。帮助您改进它以适应您的用例将会很有趣。

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. 设置服务以提供创建网址的功能:

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,开发速度至关重要)

答案 3 :(得分:0)

看来你想要的是刚刚添加到angularui project的ui-route指令。有一套很好的开箱即用选项。