Angular: complex grouped looping in HTML template

  Kiến thức lập trình

I’m recreating an existing application written in Flask, to Angular. I have a page which generates a list of events, grouped by country and region. This is what the output looks like.

[![Screenshot of events][1]][1]

Here’s the relevant code from the Jinja template

<div class="convention_list">
    {% set ns = namespace() %}
    {% set ns.active_country = '' %}
    {% set ns.active_region = '' %}

    <b>Listing {{context.conventions|length}} events</b>

    {% for convention in context.conventions %}

        {% if ns.active_country != convention.country %}
            {% set ns.active_country = convention.country %}
            {% set anchor_link = ns.active_country|lower|replace(' ', '-') %}
            <a name="{{anchor_link}}"></a>
            <h3><a href="#{{anchor_link}}" class="anchor-link" title="Link to this section">{{ns.active_country}}</a></h3>
        {% endif %}

        {% if ns.active_region != convention.region[1] %}
            {% set ns.active_region = convention.region[1] %}
            {% if ns.active_region %}
                {% set anchor_link = ns.active_country|lower|replace(' ', '-') + '-' + ns.active_region|lower|replace(' ', '-') %}
                <a name="{{anchor_link}}"></a>
                <h4><a href="#{{anchor_link}}" class="anchor-link" title="Link to this section">{{ns.active_region}}</a></h4>
            {% endif %}
        {% endif %}

        <div class="event>
            <h3>{{convention.name}}</h3>
            <div class="location">
                {{convention.city}}{% if ns.active_region %}, {{ns.active_region}}{% endif %}
            </div>
        </div>
    {% endfor %}
</div>

In my initial research it appears that Angular templates cannot set intermediate variables within a loop. But as you can see in the sample code, I need to be able to know when country and region changes so that I know whether to output headings.

The data coming in will be ordered by country > region > start date, like so:

[![enter image description here][2]][2]

Given the limitations of the template language, what is my best option for displaying this data?

Possible idea. Right now I have a simple array of events, grouping happens at the template level. But what if I pre-grouped into countries/regions. So rather than returning this:

events = [
 {event},
 {event},
]

I return this instead:

events = [
”: [
{event},
{event},
],

]


This alternate idea might work, but then what would my Angular return type look like? Right now it's easy: `Convention[]`. Thoughts?



  [1]: https://i.sstatic.net/pamngJfg.png
  [2]: https://i.sstatic.net/LhritbZd.png

LEAVE A COMMENT