如何将可选参数相关内容加载到单个角度状态?

时间:2014-05-17 23:53:59

标签: angularjs angular-ui angular-ui-router

我正在构建一个加载内容列表的前端。想想reddit或stackoverflow。像那些我希望根据不同参数加载不同内容的网站。例如,如果用户单击项目上的元标记链接,该用户将获得共享该元标记的内容列表。或者,如果用户搜索关键字,他们将根据该搜索获得内容。我已经有单独的API调用来获取基于标记,搜索关键字和默认路由的json,如果用户只是看到那里有什么。我也有一个主要处理角度的工作方式,但它有一个问题,我认为有一个更好的方法来处理这个问题。现在我的代码。我正在共享的内容设置为使用默认行为或元标记链接。搜索应该很容易从中推断,但我还没有打扰。

这里我有一个单独的路由,用于默认加载和从元标记加载内容。您会注意到两条路由共享一个控制器和一个模板。你也会注意到孩子的状态'items.detail'。我当前设置的一个问题是,无论什么参数确定加载了哪些数据,我都需要这个子状态才能工作。它会加载一个模式,其中包含更多内容细节。目前,如果我从元标记中加载数据,它显然无法从“标记”状态解析items.detail。

.state('items', {
    url: '/items',
    templateUrl: 'views/items.html',
    controller: 'mainCtrl',
    authenticate: false
}).state('items.detail', {
        url: '/{id}',
        templateUrl: 'views/item-detail.html',
        controller: 'itemDetailCtrl',
        authenticate: false
    })

.state('tags', {
    url: '/items/tag/{tag}',
    templateUrl: 'views/items.html',
    controller: 'mainCtrl',
    authenticate: false
})

这是在检查是否存在要使用的元标记然后将该内容设置为范围对象之后处理请求内容的控制器。

module.exports = function ($scope, API, $stateParams) {

    // load data for items
    if ($stateParams.tag) {

        var tag = $stateParams.tag;

        API.getItemsByTag(tag)
            .then(function (res) {
                $scope.items = res.data;
            });

    } else {

        API.getItems()
            .then(function (res) {
                $scope.items = res.data;
            });
    }


};

这是我的api调用抽象的样子

module.exports = function (Env, $http) {

    // enviroment dependent base url
    var base = Env.baseUrl;

    return {

        getItems : function (count) {
            return $http.get(base + 'items');
        },

        getItemsByTag : function (tag) {
            return $http.get(base + 'items/tags/' + tag);
        },
    };

};

根据标记链接或搜索,更改主要“项目”状态调用数据的方式可能是更好的方法吗?我可以将各种可选参数传递给单个状态吗?

旁注:你会注意到'module.exports'的语法,而不是默认的app.whatever。我正在使用browserify进行捆绑,这就是为什么它就是这样。

2 个答案:

答案 0 :(得分:1)

好吧我觉得我找到了正确的解决方案。我最终使用了查询参数,我不知道ui-router能够使用。我的控制器实际上根本不需要改变。我仍然有if语句检查它查询参数是否可用,如果是,则进行不同的api调用。以下是我的路线目前的样子。您会注意到需要在状态URL中显式声明查询参数。我没有对此进行过测试,但我相信您可以使用&符号分隔多个查询参数,它们都应该是可选的。

.state('items', {
    url: '/items?tag',
    templateUrl: 'views/items.html',
    controller: 'mainCtrl',
    authenticate: false
}).state('items.detail', {
        url: '/{id}',
        templateUrl: 'views/item-detail.html',
        controller: 'itemDetailCtrl',
        authenticate: false
    })

对我来说仍然存在的一个问题是,如果我可以在我的ui-sref中声明查询参数。我还没有能够让它工作但我目前的设置是使用href。像这样。

<a href="#/items?tag={{tag}}" class="meta-tag" ng-repeat="tag in item.tags">{{ tag }}</a>

我不知道使用ui-router的hrefs是否存在问题,但我会研究它。

答案 1 :(得分:1)

我们可以在此plunker中观察我们如何扩展此use-case的方式。 ui-sref定义的摘要:

  <a ui-sref="items({tag:'myTagOne'})">tag: myTagOne</a>
  <a ui-sref="items({tag:'myTagTwo'})">tag: myTagTwo</a> 
  <a ui-sref="items({tag:'myTagTwo', info: 'evenInfo'})">
                                       tag: myTagThree and info: evenInfo</a>

  tag already exists, was set on items/parent state
  <a ui-sref="items.detail({id: 1})">detail: 1 </a>
  <a ui-sref="items.detail({id: 2})">detail: 2 </a>

  tag could be also passed into detail
  <a ui-sref="items.detail({id: 1, tag: null})">detail: 1, tag null </a>
  <a ui-sref="items.detail({id: 2, tag: 'tg'})">detail: 2, tag 'tg' </a>

这里有一个小state定义概述。 (更多详情here

  $stateProvider
    .state('items', {
      url: '/items?tag&info',
      template:...
      controller: ...
    })
    .state('items.detail', {
      url: '/{id:[0-9]{1,8}}',
      template: ...
      controller: ...
    });

状态可以定义一些query params,如文档here所示。这些要么在选择子状态时已设置,要么也可以传递:

ui-sref="items.detail({id: 2, tag: 'tg', info : '...'})"