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

时间:2022-02-25 11:25:30

I'm building a front-end that loads a list of content. Think reddit or *. Like those sites I want to load different content based on different parameters. For example if a users clicks a meta-tag link on an item, that user will get a list of content sharing that meta-tag. Or if a user searches a keyword they will get content based on that search. I already have separate API calls for getting json based on a tag, a search keyword, and a default route if the user is just seeing what's out there. I also have a mostly working way of handling this in angular but it has an issue and I assume there is a better way to handle this. Now for the code I have. What I'm sharing is setup to work with either the default behavior or a meta-tag link. Search should be easy to extrapolate from this but I haven't bothered yet.

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

Here I have separate routes for the default load and loading content from a meta-tag. You'll notice both routes share a controller and a template. Also you'll notice the child state 'items.detail'. One issue with my current setup is that I need this child state to work no matter what parameter determined what data was loaded. It loads a modal with more detail on the content. Currently if I loaded the data from a meta-tag it obviously can't resolve items.detail from the 'tags' state.

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

Here is the controller that handles requesting content after checking if there's a meta tag to use or not and then setting that content to a scope object.

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

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


};

Here is what my api call abstractions look like

这是我的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);
        },
    };

};

What might be a better approach for changing how my main 'items' state calls data based on a tag link or search? Can I pass a variety of optional parameters to a single state?

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

Side note: You'll notice syntax with 'module.exports' instead of the default app.whatever. I'm using browserify to bundle so that's why it's like that.

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

2 个解决方案

#1


1  

The way how we can extend this use-case could be observed here in this plunker. The snippet of the ui-sref definition:

我们可以在这个阅读器中观察到我们如何扩展这个用例的方式。 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>

And here is small state defintion overview. (more details here)

这里是小型国家定义概述。 (更多细节在这里)

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

The Parent state could define some query params as documented here. These are either already set when child state is selected, or could be passed as well:

Parent状态可以定义一些查询参数,如此处所述。这些要么在选择子状态时已经设置,要么也可以传递:

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

#2


1  

Alright I think I've found the correct solution. I ended up using query parameters which I didn't know ui-router was capable of using. My controller didn't actually need to change at all. I still have the if statements checking it query parameters are available and making different api calls if they are. Here are what my routes currently look like. You'll notice the query parameters need to be declared explicitly in the state url. I haven't tested this but I believe you can separate multiple query params with ampersands and they should all be optional.

好吧,我想我找到了正确的解决方案。我最终使用了查询参数,我不知道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
    })

One question that still remains for me is if I can declare query params in my ui-sref. I haven't be able to get that to work yet but my current setup is working with an href. Like so.

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

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

I don't know if there are issues using hrefs with ui-router but I'll be researching that.

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

#1


1  

The way how we can extend this use-case could be observed here in this plunker. The snippet of the ui-sref definition:

我们可以在这个阅读器中观察到我们如何扩展这个用例的方式。 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>

And here is small state defintion overview. (more details here)

这里是小型国家定义概述。 (更多细节在这里)

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

The Parent state could define some query params as documented here. These are either already set when child state is selected, or could be passed as well:

Parent状态可以定义一些查询参数,如此处所述。这些要么在选择子状态时已经设置,要么也可以传递:

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

#2


1  

Alright I think I've found the correct solution. I ended up using query parameters which I didn't know ui-router was capable of using. My controller didn't actually need to change at all. I still have the if statements checking it query parameters are available and making different api calls if they are. Here are what my routes currently look like. You'll notice the query parameters need to be declared explicitly in the state url. I haven't tested this but I believe you can separate multiple query params with ampersands and they should all be optional.

好吧,我想我找到了正确的解决方案。我最终使用了查询参数,我不知道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
    })

One question that still remains for me is if I can declare query params in my ui-sref. I haven't be able to get that to work yet but my current setup is working with an href. Like so.

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

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

I don't know if there are issues using hrefs with ui-router but I'll be researching that.

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