12

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

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

我已经提供了构建 url 所需的一切,$routeProvider例如:$routeProvider.urlFor("MyCtrl", {id: 5})可能会很高兴。

我的主要目标是避免在视图和其他地方硬编码 url,并避免重复 url/routes 模式两次。

更新:

似乎很难解释我想要什么所以这里是我想要的确切示例:

而不是在视图中写这个:

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

我想写这个:

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

因此,如果稍后我决定更改 ProductCtrl 的路径,我将不必更新此元素中的 url。

我的目标有什么好的解决方案?

4

4 回答 4

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

于 2013-03-17T15:52:30.933 回答
2

有很多方法......自定义directiveng-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)
  }  
}

演示:http: //jsbin.com/ovemaq/3

于 2013-03-10T17:09:17.610 回答
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.设置服务以提供创建 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 个,开发速度至关重要)

于 2013-03-18T20:32:17.960 回答
0

看来您想要的是最近添加到angularui 项目中的 ui-route 指令。有一组很好的开箱即用选项。

于 2013-03-15T05:05:36.020 回答